From 6e99e18baf5ebcd41056adee76a059477794b644 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Michal=20Strehovsk=C3=BD?= Date: Mon, 24 Jun 2019 21:17:01 +0200 Subject: [PATCH] Remove AggressiveOptimization flag from System.Text (#25356) Based on conversation with Levi, I don't think this flag is needed. The flag currently controls two things: * Disqualifies the method from precompilation * Disables Tier-0 JIT for the method Removing the attribute allows us to precompile some of the methods (not all, because of `Vector`). It measurably helps improve startup time because many of the attributed methods are complex and take a while to compile. Once tier-1 JIT kicks in, the generated code should be identical to what we were getting before. --- src/System.Private.CoreLib/shared/System/Text/ASCIIUtility.cs | 11 +++-------- .../shared/System/Text/Unicode/Utf8Utility.Helpers.cs | 4 ++-- .../shared/System/Text/Unicode/Utf8Utility.Transcoding.cs | 1 - 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/System.Private.CoreLib/shared/System/Text/ASCIIUtility.cs b/src/System.Private.CoreLib/shared/System/Text/ASCIIUtility.cs index 4f7f996..b37b017 100644 --- a/src/System.Private.CoreLib/shared/System/Text/ASCIIUtility.cs +++ b/src/System.Private.CoreLib/shared/System/Text/ASCIIUtility.cs @@ -228,7 +228,6 @@ namespace System.Text goto Finish; } - [MethodImpl(MethodImplOptions.AggressiveOptimization)] private static unsafe nuint GetIndexOfFirstNonAsciiByte_Sse2(byte* pBuffer, nuint bufferLength) { // JIT turns the below into constants @@ -642,7 +641,6 @@ namespace System.Text goto Finish; } - [MethodImpl(MethodImplOptions.AggressiveOptimization)] private static unsafe nuint GetIndexOfFirstNonAsciiChar_Sse2(char* pBuffer, nuint bufferLength /* in chars */) { // This method contains logic optimized for both SSE2 and SSE41. Much of the logic in this method @@ -1006,7 +1004,7 @@ namespace System.Text /// narrows each WORD to a BYTE, then writes the 4-byte result to the output buffer /// also in machine-endian order. /// - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void NarrowFourUtf16CharsToAsciiAndWriteToBuffer(ref byte outputBuffer, ulong value) { Debug.Assert(AllCharsInUInt64AreAscii(value)); @@ -1046,7 +1044,7 @@ namespace System.Text /// narrows each WORD to a BYTE, then writes the 2-byte result to the output buffer also in /// machine-endian order. /// - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void NarrowTwoUtf16CharsToAsciiAndWriteToBuffer(ref byte outputBuffer, uint value) { Debug.Assert(AllCharsInUInt32AreAscii(value)); @@ -1069,7 +1067,6 @@ namespace System.Text /// or once elements have been converted. Returns the total number /// of elements that were able to be converted. /// - [MethodImpl(MethodImplOptions.AggressiveOptimization)] public static unsafe nuint NarrowUtf16ToAscii(char* pUtf16Buffer, byte* pAsciiBuffer, nuint elementCount) { nuint currentOffset = 0; @@ -1298,7 +1295,6 @@ namespace System.Text goto Finish; } - [MethodImpl(MethodImplOptions.AggressiveOptimization)] private static unsafe nuint NarrowUtf16ToAscii_Sse2(char* pUtf16Buffer, byte* pAsciiBuffer, nuint elementCount) { // This method contains logic optimized for both SSE2 and SSE41. Much of the logic in this method @@ -1601,7 +1597,6 @@ namespace System.Text goto Finish; } - [MethodImpl(MethodImplOptions.AggressiveOptimization)] private static unsafe nuint WidenAsciiToUtf16_Sse2(byte* pAsciiBuffer, char* pUtf16Buffer, nuint elementCount) { // JIT turns the below into constants @@ -1698,7 +1693,7 @@ namespace System.Text /// Given a DWORD which represents a buffer of 4 bytes, widens the buffer into 4 WORDs and /// writes them to the output buffer with machine endianness. /// - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void WidenFourAsciiBytesToUtf16AndWriteToBuffer(ref char outputBuffer, uint value) { Debug.Assert(AllBytesInUInt32AreAscii(value)); diff --git a/src/System.Private.CoreLib/shared/System/Text/Unicode/Utf8Utility.Helpers.cs b/src/System.Private.CoreLib/shared/System/Text/Unicode/Utf8Utility.Helpers.cs index ab29fbe..54940f9 100644 --- a/src/System.Private.CoreLib/shared/System/Text/Unicode/Utf8Utility.Helpers.cs +++ b/src/System.Private.CoreLib/shared/System/Text/Unicode/Utf8Utility.Helpers.cs @@ -64,7 +64,7 @@ namespace System.Text.Unicode /// Given a machine-endian DWORD which four bytes of UTF-8 data, interprets the input as a /// four-byte UTF-8 sequence and returns the machine-endian DWORD of the UTF-16 representation. /// - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static uint ExtractCharsFromFourByteSequence(uint value) { if (BitConverter.IsLittleEndian) @@ -760,7 +760,7 @@ namespace System.Text.Unicode /// Given a DWORD which represents a buffer of 4 ASCII bytes, widen each byte to a 16-bit WORD /// and writes the resulting QWORD into the destination with machine endianness. /// - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void Widen4AsciiBytesToCharsAndWrite(ref char outputBuffer, uint value) { if (Bmi2.X64.IsSupported) diff --git a/src/System.Private.CoreLib/shared/System/Text/Unicode/Utf8Utility.Transcoding.cs b/src/System.Private.CoreLib/shared/System/Text/Unicode/Utf8Utility.Transcoding.cs index 3b83a24..126974c 100644 --- a/src/System.Private.CoreLib/shared/System/Text/Unicode/Utf8Utility.Transcoding.cs +++ b/src/System.Private.CoreLib/shared/System/Text/Unicode/Utf8Utility.Transcoding.cs @@ -35,7 +35,6 @@ namespace System.Text.Unicode // On method return, pInputBufferRemaining and pOutputBufferRemaining will both point to where // the next byte would have been consumed from / the next char would have been written to. // inputLength in bytes, outputCharsRemaining in chars. - [MethodImpl(MethodImplOptions.AggressiveOptimization)] public static OperationStatus TranscodeToUtf16(byte* pInputBuffer, int inputLength, char* pOutputBuffer, int outputCharsRemaining, out byte* pInputBufferRemaining, out char* pOutputBufferRemaining) { Debug.Assert(inputLength >= 0, "Input length must not be negative."); -- 2.7.4