From 29f0a03758f79ec30e44bd6b5f08464d0cee1232 Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Tue, 15 Dec 2020 00:54:26 -0500 Subject: [PATCH 1/6] Optimize the initialization of the OrdinalCasing::s_sCasingTable table. The table was initialized in the .cctor and it contains a large amount of object references, so the generated cctor was 1K IL. Replace with a byte table and a loop. Fixes https://github.com/dotnet/runtime/issues/43732. --- .../System/Globalization/OrdinalCasing.Icu.cs | 95 ++++++++++++------- 1 file changed, 60 insertions(+), 35 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/OrdinalCasing.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/OrdinalCasing.Icu.cs index a10c39d02ed75e..0844be72edbb81 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/OrdinalCasing.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/OrdinalCasing.Icu.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; +using System.Threading; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; using Internal.Runtime.CompilerServices; @@ -40,40 +41,44 @@ internal static partial class OrdinalCasing // s_casingTable is covering the Unicode BMP plane only. Surrogate casing is handled separately. // Every cell in the table is covering the casing of 256 characters in the BMP. // Every cell is array of 512 character for uppercasing mapping. - private static ushort []?[] s_casingTable = + private static ushort []?[]? s_casingTable; + + // 0 - null + // 1 - s_noCasingPage + private static byte[] s_casingTableInit = { - /* 0000-07FF */ s_basicLatin, null, null, null, null, null, null, null, - /* 0800-0FFF */ null, null, null, null, null, null, null, null, - /* 1000-17FF */ null, s_noCasingPage, null, null, s_noCasingPage, s_noCasingPage, null, null, - /* 1800-1FFF */ null, null, null, null, null, null, null, null, - /* 2000-27FF */ null, null, s_noCasingPage, s_noCasingPage, null, s_noCasingPage, s_noCasingPage, s_noCasingPage, - /* 2800-2FFF */ s_noCasingPage, s_noCasingPage, s_noCasingPage, null, null, null, null, null, - /* 3000-37FF */ null, null, null, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, - /* 3800-3FFF */ s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, - /* 4000-47FF */ s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, - /* 4800-4FFF */ s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, - /* 5000-57FF */ s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, - /* 5800-5FFF */ s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, - /* 6000-67FF */ s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, - /* 6800-6FFF */ s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, - /* 7000-77FF */ s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, - /* 7800-7FFF */ s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, - /* 8000-87FF */ s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, - /* 8800-8FFF */ s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, - /* 9000-97FF */ s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, - /* 9800-9FFF */ s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, null, - /* A000-A7FF */ s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, null, s_noCasingPage, null, null, - /* A800-AFFF */ null, null, null, null, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, - /* B000-B7FF */ s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, - /* B800-BFFF */ s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, - /* C000-C7FF */ s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, - /* C800-CFFF */ s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, - /* D000-D7FF */ s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, null, - /* D800-DFFF */ s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, - /* E000-E7FF */ s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, - /* E800-EFFF */ s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, - /* F000-F7FF */ s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, - /* F800-FFFF */ s_noCasingPage, s_noCasingPage, null, null, s_noCasingPage, null, null, null, + /* 0000-07FF */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 0800-0FFF */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 1000-17FF */ 0, 1, 0, 0, 1, 1, 0, 0, + /* 1800-1FFF */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 2000-27FF */ 0, 0, 1, 1, 0, 1, 1, 1, + /* 2800-2FFF */ 1, 1, 1, 0, 0, 0, 0, 0, + /* 3000-37FF */ 0, 0, 0, 1, 1, 1, 1, 1, + /* 3800-3FFF */ 1, 1, 1, 1, 1, 1, 1, 1, + /* 4000-47FF */ 1, 1, 1, 1, 1, 1, 1, 1, + /* 4800-4FFF */ 1, 1, 1, 1, 1, 1, 1, 1, + /* 5000-57FF */ 1, 1, 1, 1, 1, 1, 1, 1, + /* 5800-5FFF */ 1, 1, 1, 1, 1, 1, 1, 1, + /* 6000-67FF */ 1, 1, 1, 1, 1, 1, 1, 1, + /* 6800-6FFF */ 1, 1, 1, 1, 1, 1, 1, 1, + /* 7000-77FF */ 1, 1, 1, 1, 1, 1, 1, 1, + /* 7800-7FFF */ 1, 1, 1, 1, 1, 1, 1, 1, + /* 8000-87FF */ 1, 1, 1, 1, 1, 1, 1, 1, + /* 8800-8FFF */ 1, 1, 1, 1, 1, 1, 1, 1, + /* 9000-97FF */ 1, 1, 1, 1, 1, 1, 1, 1, + /* 9800-9FFF */ 1, 1, 1, 1, 1, 1, 1, 0, + /* A000-A7FF */ 1, 1, 1, 1, 0, 1, 0, 0, + /* A800-AFFF */ 0, 0, 0, 0, 1, 1, 1, 1, + /* B000-B7FF */ 1, 1, 1, 1, 1, 1, 1, 1, + /* B800-BFFF */ 1, 1, 1, 1, 1, 1, 1, 1, + /* C000-C7FF */ 1, 1, 1, 1, 1, 1, 1, 1, + /* C800-CFFF */ 1, 1, 1, 1, 1, 1, 1, 1, + /* D000-D7FF */ 1, 1, 1, 1, 1, 1, 1, 0, + /* D800-DFFF */ 1, 1, 1, 1, 1, 1, 1, 1, + /* E000-E7FF */ 1, 1, 1, 1, 1, 1, 1, 1, + /* E800-EFFF */ 1, 1, 1, 1, 1, 1, 1, 1, + /* F000-F7FF */ 1, 1, 1, 1, 1, 1, 1, 1, + /* F800-FFFF */ 1, 1, 0, 0, 1, 0, 0, 0, }; [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -85,7 +90,12 @@ internal static char ToUpper(char c) return (char) s_basicLatin[(int)c]; } - ushort[]? casingTable = s_casingTable[pageNumber]; + if (s_casingTable == null) + { + InitCasingTable(); + } + + ushort[]? casingTable = s_casingTable![pageNumber]; if (casingTable == s_noCasingPage) { @@ -427,6 +437,21 @@ internal static unsafe int LastIndexOf(ReadOnlySpan source, ReadOnlySpan= 0 && pageNumber < 256); @@ -437,7 +462,7 @@ private static unsafe ushort [] InitOrdinalCasingPage(int pageNumber) char* pTable = (char*)table; Interop.Globalization.InitOrdinalCasingPage(pageNumber, pTable); } - s_casingTable[pageNumber] = casingTable; + s_casingTable![pageNumber] = casingTable; return casingTable; } } From 1218db9bf93ccf01249402c3fdba4cb7dca19e01 Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Tue, 15 Dec 2020 03:23:45 -0500 Subject: [PATCH 2/6] Compress the table further. Fix indentation. --- .../System/Globalization/OrdinalCasing.Icu.cs | 76 ++++++++++--------- 1 file changed, 40 insertions(+), 36 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/OrdinalCasing.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/OrdinalCasing.Icu.cs index 0844be72edbb81..9b8c9327fafdd9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/OrdinalCasing.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/OrdinalCasing.Icu.cs @@ -45,40 +45,42 @@ internal static partial class OrdinalCasing // 0 - null // 1 - s_noCasingPage + // The bits are in reverse order for readability, i.e. the highest order bit refers to + // the lowest index. private static byte[] s_casingTableInit = { - /* 0000-07FF */ 0, 0, 0, 0, 0, 0, 0, 0, - /* 0800-0FFF */ 0, 0, 0, 0, 0, 0, 0, 0, - /* 1000-17FF */ 0, 1, 0, 0, 1, 1, 0, 0, - /* 1800-1FFF */ 0, 0, 0, 0, 0, 0, 0, 0, - /* 2000-27FF */ 0, 0, 1, 1, 0, 1, 1, 1, - /* 2800-2FFF */ 1, 1, 1, 0, 0, 0, 0, 0, - /* 3000-37FF */ 0, 0, 0, 1, 1, 1, 1, 1, - /* 3800-3FFF */ 1, 1, 1, 1, 1, 1, 1, 1, - /* 4000-47FF */ 1, 1, 1, 1, 1, 1, 1, 1, - /* 4800-4FFF */ 1, 1, 1, 1, 1, 1, 1, 1, - /* 5000-57FF */ 1, 1, 1, 1, 1, 1, 1, 1, - /* 5800-5FFF */ 1, 1, 1, 1, 1, 1, 1, 1, - /* 6000-67FF */ 1, 1, 1, 1, 1, 1, 1, 1, - /* 6800-6FFF */ 1, 1, 1, 1, 1, 1, 1, 1, - /* 7000-77FF */ 1, 1, 1, 1, 1, 1, 1, 1, - /* 7800-7FFF */ 1, 1, 1, 1, 1, 1, 1, 1, - /* 8000-87FF */ 1, 1, 1, 1, 1, 1, 1, 1, - /* 8800-8FFF */ 1, 1, 1, 1, 1, 1, 1, 1, - /* 9000-97FF */ 1, 1, 1, 1, 1, 1, 1, 1, - /* 9800-9FFF */ 1, 1, 1, 1, 1, 1, 1, 0, - /* A000-A7FF */ 1, 1, 1, 1, 0, 1, 0, 0, - /* A800-AFFF */ 0, 0, 0, 0, 1, 1, 1, 1, - /* B000-B7FF */ 1, 1, 1, 1, 1, 1, 1, 1, - /* B800-BFFF */ 1, 1, 1, 1, 1, 1, 1, 1, - /* C000-C7FF */ 1, 1, 1, 1, 1, 1, 1, 1, - /* C800-CFFF */ 1, 1, 1, 1, 1, 1, 1, 1, - /* D000-D7FF */ 1, 1, 1, 1, 1, 1, 1, 0, - /* D800-DFFF */ 1, 1, 1, 1, 1, 1, 1, 1, - /* E000-E7FF */ 1, 1, 1, 1, 1, 1, 1, 1, - /* E800-EFFF */ 1, 1, 1, 1, 1, 1, 1, 1, - /* F000-F7FF */ 1, 1, 1, 1, 1, 1, 1, 1, - /* F800-FFFF */ 1, 1, 0, 0, 1, 0, 0, 0, + /* 0000-07FF */ 0b00000000, + /* 0800-0FFF */ 0b00000000, + /* 1000-17FF */ 0b01001100, + /* 1800-1FFF */ 0b00000000, + /* 2000-27FF */ 0b00110111, + /* 2800-2FFF */ 0b11100000, + /* 3000-37FF */ 0b00011111, + /* 3800-3FFF */ 0b11111111, + /* 4000-47FF */ 0b11111111, + /* 4800-4FFF */ 0b11111111, + /* 5000-57FF */ 0b11111111, + /* 5800-5FFF */ 0b11111111, + /* 6000-67FF */ 0b11111111, + /* 6800-6FFF */ 0b11111111, + /* 7000-77FF */ 0b11111111, + /* 7800-7FFF */ 0b11111111, + /* 8000-87FF */ 0b11111111, + /* 8800-8FFF */ 0b11111111, + /* 9000-97FF */ 0b11111111, + /* 9800-9FFF */ 0b11111110, + /* A000-A7FF */ 0b11110100, + /* A800-AFFF */ 0b00001111, + /* B000-B7FF */ 0b11111111, + /* B800-BFFF */ 0b11111111, + /* C000-C7FF */ 0b11111111, + /* C800-CFFF */ 0b11111111, + /* D000-D7FF */ 0b11111110, + /* D800-DFFF */ 0b11111111, + /* E000-E7FF */ 0b11111111, + /* E800-EFFF */ 0b11111111, + /* F000-F7FF */ 0b11111111, + /* F800-FFFF */ 0b11001000, }; [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -439,10 +441,12 @@ internal static unsafe int LastIndexOf(ReadOnlySpan source, ReadOnlySpan> (7 - (i % 8))); + if ((val & 1) == 1) table[i] = s_noCasingPage; } table[0] = s_basicLatin; @@ -456,7 +460,7 @@ private static unsafe ushort [] InitOrdinalCasingPage(int pageNumber) { Debug.Assert(pageNumber >= 0 && pageNumber < 256); - ushort [] casingTable = new ushort[256]; + ushort[] casingTable = new ushort[256]; fixed (ushort* table = casingTable) { char* pTable = (char*)table; From d9c52e882bbf8dc96437b320c418e2807de052c2 Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Tue, 15 Dec 2020 03:26:20 -0500 Subject: [PATCH 3/6] Use Volatile.Write(). --- .../src/System/Globalization/OrdinalCasing.Icu.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/OrdinalCasing.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/OrdinalCasing.Icu.cs index 9b8c9327fafdd9..99f799a1c7a377 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/OrdinalCasing.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/OrdinalCasing.Icu.cs @@ -452,8 +452,7 @@ private static void InitCasingTable() table[0] = s_basicLatin; // Publish - Interlocked.MemoryBarrier(); - Interlocked.CompareExchange(ref s_casingTable, table, null); + Volatile.Write(ref s_casingTable, table); } private static unsafe ushort [] InitOrdinalCasingPage(int pageNumber) @@ -466,7 +465,7 @@ private static unsafe ushort [] InitOrdinalCasingPage(int pageNumber) char* pTable = (char*)table; Interop.Globalization.InitOrdinalCasingPage(pageNumber, pTable); } - s_casingTable![pageNumber] = casingTable; + Volatile.Write(ref s_casingTable![pageNumber], casingTable); return casingTable; } } From c6d7c3fe6e24d1c2e1f5e0d90841fe30c9dc8743 Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Tue, 15 Dec 2020 03:31:37 -0500 Subject: [PATCH 4/6] Store the table as a ReadOnlySpan. --- .../src/System/Globalization/OrdinalCasing.Icu.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/OrdinalCasing.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/OrdinalCasing.Icu.cs index 99f799a1c7a377..e263185cf8f787 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/OrdinalCasing.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/OrdinalCasing.Icu.cs @@ -47,7 +47,7 @@ internal static partial class OrdinalCasing // 1 - s_noCasingPage // The bits are in reverse order for readability, i.e. the highest order bit refers to // the lowest index. - private static byte[] s_casingTableInit = + private static ReadOnlySpan s_casingTableInit => new byte[32] { /* 0000-07FF */ 0b00000000, /* 0800-0FFF */ 0b00000000, From 5f4bed186b13c6e3b57254c830b7cd6bef418618 Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Tue, 15 Dec 2020 21:33:50 -0500 Subject: [PATCH 5/6] Initialize the table in the static ctor. Add back the original table as a comment. --- .../System/Globalization/OrdinalCasing.Icu.cs | 51 +++++++++++++++---- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/OrdinalCasing.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/OrdinalCasing.Icu.cs index e263185cf8f787..cb949baae4d571 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/OrdinalCasing.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/OrdinalCasing.Icu.cs @@ -41,7 +41,45 @@ internal static partial class OrdinalCasing // s_casingTable is covering the Unicode BMP plane only. Surrogate casing is handled separately. // Every cell in the table is covering the casing of 256 characters in the BMP. // Every cell is array of 512 character for uppercasing mapping. - private static ushort []?[]? s_casingTable; + private static ushort []?[]? s_casingTable = InitCasingTable(); + + /* + The table is initialized to: + { + // 0000-07FF // s_basicLatin, null, null, null, null, null, null, null, + // 0800-0FFF // null, null, null, null, null, null, null, null, + // 1000-17FF // null, s_noCasingPage, null, null, s_noCasingPage, s_noCasingPage, null, null, + // 1800-1FFF // null, null, null, null, null, null, null, null, + // 2000-27FF // null, null, s_noCasingPage, s_noCasingPage, null, s_noCasingPage, s_noCasingPage, s_noCasingPage, + // 2800-2FFF // s_noCasingPage, s_noCasingPage, s_noCasingPage, null, null, null, null, null, + // 3000-37FF // null, null, null, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, + // 3800-3FFF // s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, + // 4000-47FF // s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, + // 4800-4FFF // s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, + // 5000-57FF // s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, + // 5800-5FFF // s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, + // 6000-67FF // s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, + // 6800-6FFF // s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, + // 7000-77FF // s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, + // 7800-7FFF // s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, + // 8000-87FF // s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, + // 8800-8FFF // s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, + // 9000-97FF // s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, + // 9800-9FFF // s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, null, + // A000-A7FF // s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, null, s_noCasingPage, null, null, + // A800-AFFF // null, null, null, null, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, + // B000-B7FF // s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, + // B800-BFFF // s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, + // C000-C7FF // s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, + // C800-CFFF // s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, + // D000-D7FF // s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, null, + // D800-DFFF // s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, + // E000-E7FF // s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, + // E800-EFFF // s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, + // F000-F7FF // s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, s_noCasingPage, + // F800-FFFF // s_noCasingPage, s_noCasingPage, null, null, s_noCasingPage, null, null, null, + }; +*/ // 0 - null // 1 - s_noCasingPage @@ -92,11 +130,6 @@ internal static char ToUpper(char c) return (char) s_basicLatin[(int)c]; } - if (s_casingTable == null) - { - InitCasingTable(); - } - ushort[]? casingTable = s_casingTable![pageNumber]; if (casingTable == s_noCasingPage) @@ -439,7 +472,7 @@ internal static unsafe int LastIndexOf(ReadOnlySpan source, ReadOnlySpan Date: Tue, 15 Dec 2020 23:57:33 -0500 Subject: [PATCH 6/6] Make s_casingTable non-nullable. --- .../src/System/Globalization/OrdinalCasing.Icu.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/OrdinalCasing.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/OrdinalCasing.Icu.cs index cb949baae4d571..71da4dcfeba11a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/OrdinalCasing.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/OrdinalCasing.Icu.cs @@ -41,7 +41,7 @@ internal static partial class OrdinalCasing // s_casingTable is covering the Unicode BMP plane only. Surrogate casing is handled separately. // Every cell in the table is covering the casing of 256 characters in the BMP. // Every cell is array of 512 character for uppercasing mapping. - private static ushort []?[]? s_casingTable = InitCasingTable(); + private static ushort []?[] s_casingTable = InitCasingTable(); /* The table is initialized to: @@ -130,7 +130,7 @@ internal static char ToUpper(char c) return (char) s_basicLatin[(int)c]; } - ushort[]? casingTable = s_casingTable![pageNumber]; + ushort[]? casingTable = s_casingTable[pageNumber]; if (casingTable == s_noCasingPage) { @@ -496,7 +496,7 @@ private static unsafe ushort [] InitOrdinalCasingPage(int pageNumber) char* pTable = (char*)table; Interop.Globalization.InitOrdinalCasingPage(pageNumber, pTable); } - Volatile.Write(ref s_casingTable![pageNumber], casingTable); + Volatile.Write(ref s_casingTable[pageNumber], casingTable); return casingTable; } }