头图

We are happy to release .NET 6 Preview 7. This is our last preview before entering the (two) release candidate (RC) period. Before we slowed down the release speed, the team had been staying up all night and doing their best to get the last set of features. In this version, you will see the final touches on various features, as well as a large number of overall release features. From this point of view, the team will focus on achieving uniform (high) quality for all functions so that .NET 6 is ready for your production workload.

On the topic of production workloads, it is worth reminding everyone that the .NET sites and Bing.com have been running on .NET 6 since Preview 1. We are discussing the use of .NET 6 RC for production with various teams (Microsoft and others). If you are interested and want guidance on how to deal with this issue, please contact dotnet@microsoft.com. We are always happy to talk to early adopters.

.NET 6 Preview 7 for Linux, macOS and Windows.

  • installer and binary files
  • container image
  • Linux software package
  • Release Notes
  • API difference
  • Known issues
  • GitHub issue tracker

Please refer to .NET MAUI and ASP.NET Core for more details about the new features in client and web application scenarios.

.NET website:

https://dotnet.microsoft.com/?WT.mc_id=dev?ocid=AID3039170

Bing.com:

https://cn.bing.com/

.NET 6 Preview 7:

https://dotnet.microsoft.com/download/dotnet/6.0?WT.mc_id=dev?ocid=AID3039170

Installer and binaries:

https://dotnet.microsoft.com/download/dotnet/6.0?WT.mc_id=dev?ocid=AID3039170

Container image:

https://hub.docker.com/_/microsoft-dotnet?WT.mc_id=dev?ocid=AID3039170

Linux package:

https://github.com/dotnet/core/blob/main/release-notes/6.0/install-linux.md?WT.mc_id=dev?ocid=AID3039170

Release notes:

https://github.com/dotnet/core/blob/main/release-notes/6.0/README.md?WT.mc_id=dev?ocid=AID3039170

API differences:

https://github.com/dotnet/core/tree/main/release-notes/6.0/preview/api-diff/preview7

Known issues:

https://github.com/dotnet/core/blob/main/release-notes/6.0/known-issues.md

GitHub issue tracker:

https://github.com/dotnet/core/issues/6554

.NET MAUI:

https://devblogs.microsoft.com/dotnet/announcing-net-maui-preview-7/?WT.mc_id=dev?ocid=AID3039170

ASP.NET Core:

https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-6-preview-7/?WT.mc_id=dev?ocid=AID3039170

.NET 6 Preview 7 has been tested and is by 16156f84c41a22 Visual Studio 2022 Preview 3 . Visual Studio 2022 enables you to take advantage of the Visual Studio tools developed for .NET 6, such as development in .NET MAUI, hot reloading of C# applications, real-time preview of new WebForms web pages, and other performance improvements in the IDE experience. Visual Studio Code also supports .NET 6. The latest version of Visual Studio Code's C# extension has been updated for .NET 6 Preview 7 and includes support for C# 10.

Check out new conversation thread for in-depth engineer-to-engineer discussions on the latest .NET features. We also published a post about string interpolation in C# 10 and .NET 6 preview feature in .NET 6-General Mathematics .

Visual Studio 2022 Preview 3:

https://dotnet.microsoft.com/download/dotnet/6.0?WT.mc_id=dev?ocid=AID3039170

Visual Studio Code:

https://code.visualstudio.com/docs/languages/dotnet

C# extension of Visual Studio Code:

https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csharp

New conversation post:

https://devblogs.microsoft.com/dotnet/category/conversations/

String interpolation in C# 10 and preview function of .NET 6 in .NET 6-General Mathematics:

https://devblogs.microsoft.com/dotnet/string-interpolation-in-c-10-and-net-6/

.NET SDK: Modern C# project template

We updated the .NET SDK template to use the latest C# language features and modes. We haven't revisited templates in terms of new language features for a while. It's time to do this, and we will ensure that the template uses new and modern features in the future.

The following language features are used in the new template:

  • Top-level statement
  • Asynchronous Main
  • Global using directive (default value driven by SDK)
  • File-wide namespace
  • New expression of target type
  • Nullable reference type

You may be wondering why we enable certain features through templates instead of enabling them by default in projects targeting .NET 6. We agree that you need to do some work to upgrade the application to the new version of .NET to improve the default behavior of the platform. This allows us to improve the product without complicating the project documentation over time. However, some features of the model can be destructive, such as nullable reference types. We don’t want to associate these features with an upgraded experience, but we want to leave the choice to you, no matter when and where. The template is a much lower risk pivot point where we can set a new "good default model" for new code with little subsequent impact. Enabling these features through the project template gives us the best of both worlds: the new code starts by enabling these features, but the existing code is not affected when upgrading.

Updated .NET SDK template:

https://github.com/dotnet/templating/issues/3359

1. Console template

The console template shows the biggest change. Because of the top-level statement and the global using directive, it is now (in fact) a line of code.

// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");

The .NET 5 version of the same template includes a few lines of familiar code, which previously had to be used by even single lines of code.

using System;
​
namespace Company.ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");
        }
    }
}

The project file of the console template has also been changed to enable the nullable reference type feature, as shown in the following example.

<Project Sdk="Microsoft.NET.Sdk">
​
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <Nullable>enable</Nullable>
  </PropertyGroup>
​
</Project>

Other templates also support nullable, implicit global use, and file-wide namespaces, including ASP.NET Core and class libraries.

Nullable reference type:

https://docs.microsoft.com/zh-cn/dotnet/csharp/nullable-references?WT.mc_id=dev?ocid=AID3039170

2. ASP.NET web page template

Web templates also reduce the number of lines of code and use the same functions.

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
​
if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
​
app.MapGet("/", () => "Hello World!");
​
app.Run();

3. ASP.NET MVC template

The mvc template is similar in structure. In this example, we have merged Program.cs and Startup.cs into one file (Program.cs) for further simplification.

var builder = WebApplication.CreateBuilder(args);
​
// Add services to the container.
builder.Services.AddControllersWithViews();
​
var app = builder.Build();
​
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}
​
app.UseHttpsRedirection();
app.UseStaticFiles();
​
app.UseRouting();
​
app.UseAuthorization();
​
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
​
app.Run();

4. Template compatibility

For compatibility issues with using the new template, please refer to the following documents.

Earlier .NET versions do not support C# code in templates:

https://docs.microsoft.com/zh-cn/dotnet/core/compatibility/sdk/6.0/csharp-template-code?WT.mc_id=dev?ocid=AID3039170

Implicit namespace import:

https://docs.microsoft.com/zh-cn/dotnet/core/compatibility/sdk/6.0/implicit-namespaces?WT.mc_id=dev?ocid=AID3039170

Library: Reflection API for nullable information

Nullable reference types are an important feature for writing reliable code. It is suitable for writing code, but not for (until now) checking it. new reflection API enables you to determine the nullability of the parameters and return values of a given method. For example, these new APIs are critical to reflection-based tools and serializers.

For context, we .NET 5 in added to the .NET libraries that can be empty comment (6 and .NET completed), and is doing the same thing for this version of ASP.NET Core. We have also seen developers adopt the nullable for their projects.

Using the type information may be null custom attributes stored in the metadata . In principle, anyone can read custom attributes, but this is not ideal, because the use of encoding is very important.

The following examples demonstrate the use of the new API in several different scenarios.

New reflection API:

https://github.com/dotnet/runtime/issues/29723

Developers use nullable types for their projects:

https://github.com/jellyfin/jellyfin/blob/c07e83fdf87e61f30e4cca4e458113ac315918ae/Directory.Build.props#L5

The custom attributes are stored in metadata:

https://github.com/dotnet/roslyn/blob/main/docs/features/nullable-metadata.md

1. Get top nullable information

Suppose you are implementing a serializer. Using these new APIs, serializers can check whether a given property can be set to null:

private NullabilityInfoContext _nullabilityContext = new NullabilityInfoContext();
​
private void DeserializePropertyValue(PropertyInfo p, object instance, object? value)
{
    if (value is null)
    {
        var nullabilityInfo = _nullabilityContext.Create(p);
        if (nullabilityInfo.WriteState is not NullabilityState.Nullable)
        {
            throw new MySerializerException($"Property '{p.GetType().Name}.{p.Name}'' cannot be set to null.");
        }
    }
​
    p.SetValue(instance, value);
}

2. Get nested nullable information

Nullable types have special treatment for objects that can (formally) store other objects (such as arrays and tuples). For example, you can specify that the array object (as a variable, or as part of the signature of a type member) must be non-empty, but the elements can be empty, and vice versa. This extra level of specificity can be checked using the new reflection API, as shown in the following example.

class Data
{
    public string?[] ArrayField;
    public (string?, object) TupleField;
}
private void Print()
{
    Type type = typeof(Data);
    FieldInfo arrayField = type.GetField("ArrayField");
    FieldInfo tupleField = type.GetField("TupleField");
    NullabilityInfoContext context = new ();
​
    NullabilityInfo arrayInfo = context.Create(arrayField);
    Console.WriteLine(arrayInfo.ReadState);        // NotNull
    Console.WriteLine(arrayInfo.Element.State);    // Nullable
​
    NullabilityInfo tupleInfo = context.Create(tupleField);
    Console.WriteLine(tupleInfo.ReadState);                      // NotNull
    Console.WriteLine(tupleInfo.GenericTypeArguments [0].State); // Nullable
    Console.WriteLine(tupleInfo.GenericTypeArguments [1].State); // NotNull
}

Library: ZipFile respects Unix file permissions

When extracting zip compressed files on Unix-like operating systems, the System.IO.Compression.ZipFile class can now capture Unix file permissions during file creation and setting. This change allows executable files to be transferred back and forth via zip, which means you no longer need to modify file permissions after unzipping the zip to make the file executable. It also respects the read/write permissions of users, groups, and others.

If the zip does not contain file permissions (because it was created on Windows, or using a tool that does not capture permissions, such as earlier versions of .NET), the extracted file will get the default file permissions, just like any other newly created file .

Unix file permissions also apply to other zip tools, including:

Info-ZIP:

https://sourceforge.net/projects/infozip/

7-Zip:

https://www.7-zip.org/

.NET 7 Early Feature Preview: General Mathematics

For .NET 6, we have built to mark the API as "in preview" . This new approach will allow us to provide and develop preview capabilities across multiple major releases. In order to use the preview API, the project needs to explicitly choose to use the preview function. Starting with .NET 6 RC1, if you use the preview function without explicitly selecting it, you will see build errors with actionable messages. In future versions, the preview function may change in a disruptive way. This is why they need you to choose to add.

One of the features we previewed in .NET 6 is static abstract interface members. It allows you to define static abstract methods (including operators) in the interface. For example, it is now possible to implement algebraic generic methods. For some people, this feature will be an absolutely outstanding improvement that we will provide this year. It may be the most important new system function since Span<T>.

The following example uses IEnumerable<T>, and since T is constrained to be INumber<T> (possibly INumber<int>), it is able to sum all values.

public static T Sum<T>(IEnumerable<T> values)
    where T : INumber<T>
{
    T result = T.Zero;
​
    foreach (var value in values)
    {
        result += value;
    }
​
    return result;
}

This is valid because INumber<T> defines various (static) operator overloads that interface implementers must satisfy. IAdditionOperators probably the easiest new interface to understand, INumber<T> itself is derived from it.

All of this is supported by a new feature that allows static abstract members to be declared in the interface. This enables the interface to expose operators and other static methods, such as Parse or Create, and those implemented by derived types. Please refer to our related blog post for more details!

All the features mentioned are in the preview version of .NET 6 and are not supported for use in production. We would be grateful for your feedback on using them. We intend to continue to develop and improve general math functions and the runtime and C# functions that support them in .NET 7. We want to make major changes to the current experience, which is part of the reason why the new API is marked as "in preview"."

Mark the API as "Previewing":

https://github.com/dotnet/designs/blob/main/accepted/2021/preview-features/preview-features.md

INumber<T>:

https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/INumber.cs

Operator overloading:

https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/operators/operator-overloading?WT.mc_id=dev?ocid=AID3039170

IAdditionOperators:

https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/IAdditionOperators.cs

Related blog posts:

https://devblogs.microsoft.com/dotnet/preview-features-in-net-6-generic-math/

Library: NativeMemory API

We have added the new native memory allocation API exposed through System.Runtime.InteropServices.NativeMemory. These APIs are equivalent to malloc, free, realloc, and calloc C APIs, and also include APIs for aligned allocation.

You may be wondering how to understand these APIs. First, they are low-level APIs for low-level code and algorithms. Application developers rarely use these. Another way to consider these APIs is similar to the APIs built 16156f84c429b3 platform, which are low-level .NET APIs for chip instructions. These APIs are very similar, but expose low-level APIs for memory-related operations.

Native memory allocation API:

https://github.com/dotnet/runtime/pull/54006

Inner platform:

https://github.com/dotnet/designs/blob/main/accepted/2018/platform-intrinsics.md

Library: System.Text.Json serialization notification

The System.Text.Json serializer now exposes notifications as part of the (de)serialization operation. They are useful for default values and verification. To use them, implement one or more interfaces IJsonOnDeserialized, IJsonOnDeserializing, IJsonOnSerialized, or IJsonOnSerializing in the System.Text.Json.Serialization namespace.

This is an example verified during JsonSerializer.Serialize() and JsonSerializer.Deserialize() to ensure that the FirstName property is not empty.

 public class Person : IJsonOnDeserialized, IJsonOnSerializing
  {
      public string FirstName{ get; set; }
​
      void IJsonOnDeserialized.OnDeserialized() => Validate(); // Call after deserialization
      void IJsonOnSerializing.OnSerializing() => Validate(); // Call before serialization
​
      private void Validate()
      {
          if (FirstName is null)
          {
              throw new InvalidOperationException("The 'FirstName' property cannot be 'null'.");
          }
      }
  }

Previously, you needed to implement a custom converter to achieve this functionality.

Library: System.Text.Json serialization property sorting

We also added the ability to control the serialization order of attributes through System.Text.Json.Serialization.JsonPropertyOrderAttribute. That is, the integer in the specified order. Smaller integers are serialized first; attributes without attributes have a default sort value of 0.

The following example specifies that JSON should be serialized in the order of Id, City, FirstName, LastName:

public class Person
{
    public string City { get; set; } // No order defined (has the default ordering value of 0)
​
    [JsonPropertyOrder(1)] // Serialize after other properties that have default ordering
    public string FirstName { get; set; }
​
    [JsonPropertyOrder(2)] // Serialize after FirstName
    public string LastName { get; set; }
​
    [JsonPropertyOrder(-1)] // Serialize before other properties that have default ordering
    public int Id { get; set; }
}

Previously, the order of serialization was determined by the order of reflection, which was neither deterministic nor would lead to a specific required order.

Library: Use System.Text.Json.Utf8JsonWriter to "write raw" JSON

When writing JSON payloads with Utf8JsonWriter, sometimes you need integrate "raw" JSON .

E.g:

  • I have a sequence of bytes that I want to write out on the web, and I know what I am doing (as shown in the example below).
  • I have a blob, I think it represents JSON content and I want to encapsulate it, I need to make sure that the encapsulation and its internal content remain formatted correctly.
JsonWriterOptions writerOptions = new() { WriteIndented = true, };
​
using MemoryStream ms = new();
using UtfJsonWriter writer = new(ms, writerOptions);
​
writer.WriteStartObject();
writer.WriteString("dataType", "CalculationResults");
​
writer.WriteStartArray("data");
​
foreach (CalculationResult result in results)
{
    writer.WriteStartObject();
    writer.WriteString("measurement", result.Measurement);
​
    writer.WritePropertyName("value");
    // Write raw JSON numeric value using FormatNumberValue (not defined in the example)
    byte[] formattedValue = FormatNumberValue(result.Value);
    writer.WriteRawValue(formattedValue, skipValidation: true);
​
    writer.WriteEndObject();
}
​
writer.WriteEndArray();
writer.WriteEndObject();

The following is a description of what the above code (especially FormatNumberValue) is doing. For performance, System.Text.Json omits the decimal point/value when the number is an integer, such as 1.0. The basic principle is that writing fewer bytes is good for performance. In some cases, it may be important to keep the decimal value, because consumers treat numbers without decimals as integers, otherwise they are treated as double-precision numbers. This new "original value" model allows you to control it anytime, anywhere.

Integrate "raw" JSON:

https://github.com/dotnet/runtime/issues/1784

Library: Synchronous stream overload on JsonSerializer

We added new synchronization API , which is used to serialize and deserialize JSON data to a stream. You can see this in the following example.

using MemoryStream ms = GetMyStream();
MyPoco poco = JsonSerializer.Deserialize<MyPoco>(ms);

By accepting JsonTypeInfo<T> or JsonSerializerContext instances, these new synchronization APIs include overloads that are compatible and available System.Text.Json source generator

New synchronization API:

https://github.com/dotnet/runtime/issues/1574

System.Text.Json source generator:

https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-source-generator/

Library: Removed System.Text.Json.Nodes.JsonNode's support for dynamic

The support for C# dynamic type in JsonSerializer has been removed. We added dynamic support in Preview 4, but later determined it was a bad design choice, including making it a required dependency of the JsonNode type.

major change from .NET 6 preview to preview standpoint, but not from .NET 5 to 6.

dynamic:

https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/builtin-types/reference-types#the-dynamic-type?WT.mc_id=dev?ocid=AID3039170

Breaking changes:

https://github.com/dotnet/docs/issues/25105

Library: System.Diagnostics Propagators

In the past few years, we have been improving the support OpenTelemetry One of the key aspects of achieving strong support is to ensure that all components that need to participate in telemetry production generate network headers in the correct format. This is really difficult to do, especially with the changes in the OpenTelemetry specification. OpenTelemetry defines the propagate to help solve this situation. We are using propagation to enable a common model for header customization.

The background of the broader concept:

  • OpenTelemetry specification-memory representation of distributed tracking data structure.
  • OpenTelemetry Span — the building block used for tracking, represented by System.Diagnostics.Activity .NET.
  • W3C TraceContext — Specification on how to propagate these distributed trace data structures through the well-known HTTP headers.

The following code demonstrates the general method of using propagation.

DistributedContextPropagator propagator = DistributedContextPropagator.Current;
propagator.Inject(activity, carrier, (object theCarrier, string fieldName, string value) =>
{
   // Extract the context from the activity then inject it to the carrier.
});

You can also choose to use different communicators.

// Set the current propagation behavior to not transmit any distributed context information in outbound network messages.
DistributedContextPropagator.Current = DistributedContextPropagator.CreateNoOutputPropagator();
OpenTelemetry:

https://devblogs.microsoft.com/dotnet/opentelemetry-net-reaches-v1-0/

spread:

https://opentelemetry.lightstep.com/core-concepts/context-propagation/

OpenTelemetry:

https://opentelemetry.io/

OpenTelemetry Span:

https://opentelemetry.lightstep.com/spans/

System.Diagnostics.Activity:

https://docs.microsoft.com/zh-cn/dotnet/api/system.diagnostics.activity?view=net-5.0

W3C TraceContext:

https://www.w3.org/TR/trace-context/

The DistributedContextPropagator abstract class determines whether and how distributed context information is encoded and decoded when traversing the network. The encoding can be transmitted through any network protocol that supports key-value string pairs. DistributedContextPropagator injects the value into the carrier and extracts the value from the carrier as a key/value string pair. By adding support for the communicator, we achieved two things:

  • You no longer need to use the W3C TraceContext header. You can write a custom propagator (ie, use your own header names, including not sending them at all) without the need for HttpClient, ASP.NET Core libraries with prior knowledge of this custom format
  • If you use a custom transport (such as message queue) to implement the library, you can now support various connection formats, as long as you support sending and receiving text mapping (such as Dictionary<string, string>)

Most application code does not need to use this feature directly, but if you use OpenTelemetry, you will most likely see it in the call stack. If you care about tracking and causality, some library code will want to participate in this model.

W3C TraceContext:

https://www.w3.org/TR/trace-context/

Library: Simplified calling mode for encryption operations

The .NET encryption and decryption routines are designed around streams, and there is no real concept that defines when the payload is already in memory. The new Encrypt- and Decrypt- methods on SymmetricAlgorithm accelerate the situation that already exists in memory, aiming to provide clear information to callers and code reviewers. In addition, they support reading from and writing to the span.

The new simplified method provides a straightforward way to use the encryption API:

private static byte[] Decrypt(byte[] key, byte[] iv, byte[] ciphertext)
{
    using (Aes aes = Aes.Create())
    {
        aes.Key = key;
​
        return aes.DecryptCbc(ciphertext, iv);
    }
}

With the new Encrypt- and Decrypt-methods, only the key attribute from the SymmetricAlgorithm instance is used. The new DecryptCbc method supports the selection of padding algorithm, but PKCS#7 is often used with CBC, so it is the default parameter. If you like more clarity, just specify it:

private static byte[] Decrypt(byte[] key, byte[] iv, byte[] ciphertext)
{
    using (Aes aes = Aes.Create())
    {
        aes.Key = key;
​
        return aes.DecryptCbc(ciphertext, iv, PaddingMode.PKCS7);
    }
}

You can see that the existing model (using .NET 5) requires more pipelines to achieve the same result.

private static byte[] Decrypt(byte[] key, byte[] iv, byte[] ciphertext)
{
    using (Aes aes = Aes.Create())
    {
        aes.Key = key;
        aes.IV = iv;
​
        // These are the defaults, but let's set them anyways.
        aes.Padding = PaddingMode.PKCS7;
        aes.Mode = CipherMode.CBC;
​
        using (MemoryStream destination = new MemoryStream())
        using (ICryptoTransform transform = aes.CreateDecryptor())
        using (CryptoStream cryptoStream = new CryptoStream(destination, transform, CryptoStreamMode.Write))
        {
            cryptoStream.Write(ciphertext, 0, ciphertext.Length);
            cryptoStream.FlushFinalBlock();
            return destination.ToArray();
        }
    }
}

Library: Full case mapping support in global invariant mode

Global invariant mode enables you to eliminate the dependence of applications on global data and behavior in exchange for smaller applications (mainly on Linux). We improved the global invariant mode to support the case mapping of the complete Unicode character set. Previously, this mode only supported ASCII range characters for String.ToUpper, String.ToLower and string comparison, as well as search operations IgnoreCase

The Alpine-based .NET container image is the only environment enables the global environment mode

Global invariant mode:

https://github.com/dotnet/runtime/blob/main/docs/design/features/globalization-invariant-mode.md

Improved global invariant mode:

https://docs.microsoft.com/zh-cn/dotnet/core/compatibility/globalization/6.0/culture-creation-invariant-mode?WT.mc_id=dev?ocid=AID3039170

IgnoreCase:

https://docs.microsoft.com/zh-cn/dotnet/api/system.globalization.compareoptions?WT.mc_id=dev&view=net-5.0

The global environment mode is enabled by default:

https://github.com/dotnet/dotnet-docker/blob/b7eeae802bcf3b9793ae49992ce4bb8d16c504c8/src/runtime-deps/5.0/alpine3.13/arm32v7/Dockerfile#L20

Runtime: W^X (write or execute) supports all platforms and architectures

The runtime now has a mode in which it does not create or use any writable and executable memory pages at the same time. All executable memory is mapped as read-only. This feature has been enabled on macOS (for Apple Silicon). On Apple Silicon machines, simultaneous writable and executable memory mapping is prohibited.

This feature is now enabled and supported on all other platforms as an optional experience. On these platforms, the generation/modification of executable code is done through separate read-write memory mapping. This is true for both the JIT code and the helper generated at runtime. These mappings are created at a virtual memory address different from the executable code address, and only exist for a short time when writing is performed. For example, JIT now generates code into a temporary buffer, and after the entire method is JIT, it uses a single memory copy function call to copy the code into executable memory. And the writable mapping life cycle only spans the time of memory copy.

This new feature can be enabled by setting the environment variable DOTNET_EnableWriteXorExecute to 1. This feature is optional in .NET 6, because it has a boot regression (except for Apple Silicon). In our ASP.Net benchmark test, when compiled with Ready To Run (R2R), the regression is about 10%. However, the measured steady-state performance is the same with and without this function. For applications whose startup performance is not important, we recommend enabling this feature to improve the security it provides. We intend to solve the performance regression problem in .NET 7 and enable this feature by default at that time.

Runtime: CodeGen change log

The following changes were made in the code generation in Preview 7.

1. Community PR

The following PRs are all from @SingleAccrtion :

  • Optimize CAST when running on 32-bit targets (int <- long)#53040

https://github.com/dotnet/runtime/pull/53040

  • Eliminate chained conversions to small types at runtime #52561

https://github.com/dotnet/runtime/pull/52561

  • Remove some unneeded code from the division deformation runtime #53464

https://github.com/dotnet/runtime/pull/53464

  • Fix CQ regression and correctness errors in long muls runtime deformation #53566

https://github.com/dotnet/runtime/pull/53566

  • Don't eliminate FP type coercion when optimizing narrow storage operation #53667

https://github.com/dotnet/runtime/pull/53667

  • Move "don't zero extension setcc" optimization to reduce running time #53778

https://github.com/dotnet/runtime/pull/53778

  • Disable implementation-defined coercion runtime folding #53782

https://github.com/dotnet/runtime/pull/53782

  • Add args description for VNF_MapStore and VNF_MapSelect runtime #54108

https://github.com/dotnet/runtime/pull/54108

  • Import cgt.un(op, 0) as NE(op, 0) runtime #54539

https://github.com/dotnet/runtime/pull/54539

  • Use local assertion props to omit casts when returning to runtime #55632

https://github.com/dotnet/runtime/pull/55632

@SingleAccrtion:

https://github.com/SingleAccretion

2. Dynamic PGO

The following PR supports dynamic PGO project .

  • [JIT] Improve inliner: new heuristic, relying on PGO data runtime #52708

https://github.com/dotnet/runtime/pull/52708

  • Inline: Extend the IL restriction of the calling site and allow inline switches. Runtime #55478

https://github.com/dotnet/runtime/pull/55478

  • JIT: Enable GDV when static class inference fails. Running time #55660

https://github.com/dotnet/runtime/pull/55660

Dynamic PGO projects:

https://github.com/dotnet/runtime/issues/43618

3.LSRA

The following PR supports LRSA project .

  • Overflow single-defined variables during definition to avoid further overflow during runtime #54345

https://github.com/dotnet/runtime/pull/54345

  • Mark vars as do not enreg in minopts. Runtime #54998

https://github.com/dotnet/runtime/pull/54998

LRSA project:

https://github.com/dotnet/runtime/issues/43318

4. Cycle optimization

The following PR improves loop optimization.

  • Improve loop cloning, debug and improve runtime #55299

https://github.com/dotnet/runtime/pull/55299

  • Support array cloning loop when running with structure index expression #55612

https://github.com/dotnet/runtime/pull/55612

  • Increase the maximum cycle of RyuJIT optimization from 16 to 64. runtime#55614

https://github.com/dotnet/runtime/pull/55614

5. Structure

The following PR has improved structure handling.

  • Register the structure on win x64. Running time #55045

https://github.com/dotnet/runtime/pull/55045

  • Enreg builds x86 windows. Running time #55535

https://github.com/dotnet/runtime/pull/55535

  • StructEnreg is enabled by default on all platforms. Running time #55558

https://github.com/dotnet/runtime/pull/55558

  • Improve TryTransformStoreObjAsStoreInd optimization. Runtime #55727

https://github.com/dotnet/runtime/pull/55727

6. Optimize

The following PR improves general optimization.

  • "==0" optimization in Boolean logic #13573 runtime#49548

https://github.com/dotnet/runtime/pull/49548

  • Allow implicit expansion when tail call runtime #54864

https://github.com/dotnet/runtime/pull/54864

Concluding remarks

We were at the time of the release, and we considered completing new features and improvements. Good job, team. This is the end of another season of .NET preview.
We continue to hope and rely on your feedback. We will focus the rest of .NET 6 on regressions (features and performance) and bugs found in new features. In most cases, functional improvements need to wait for .NET 7. Please share any and all your feedback, we are happy to categorize it.
Thanks to everyone who contributed to making .NET 6 another great version.
Thank you for being a .NET developer.


Scan the QR code to follow Microsoft MSDN to get more first-hand technical information and official learning materials from Microsoft!

image.png


微软技术栈
423 声望997 粉丝

微软技术生态官方平台。予力众生,成就不凡!微软致力于用技术改变世界,助力企业实现数字化转型。