From: Zoltan Varga Date: Thu, 17 Dec 2020 23:02:51 +0000 (-0500) Subject: Optimize the initialization of the OrdinalCasing::s_sCasingTable table. (#46061) X-Git-Tag: submit/tizen/20210909.063632~4083 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ca2aecbc1431ecbcef92878048bbc0396651ce8a;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Optimize the initialization of the OrdinalCasing::s_sCasingTable table. (#46061) --- 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 a10c39d..71da4dc 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,84 @@ namespace System.Globalization // 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, + // 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 + // The bits are in reverse order for readability, i.e. the highest order bit refers to + // the lowest index. + private static ReadOnlySpan s_casingTableInit => new byte[32] + { + /* 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)] @@ -427,17 +472,31 @@ namespace System.Globalization } } + private static ushort[]?[] InitCasingTable() + { + ushort[]?[] table = new ushort[]?[s_casingTableInit.Length * 8]; + for (int i = 0; i < s_casingTableInit.Length * 8; ++i) + { + // The bits are in reverse order + byte val = (byte)(s_casingTableInit[i / 8] >> (7 - (i % 8))); + if ((val & 1) == 1) + table[i] = s_noCasingPage; + } + table[0] = s_basicLatin; + return table; + } + 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; Interop.Globalization.InitOrdinalCasingPage(pageNumber, pTable); } - s_casingTable[pageNumber] = casingTable; + Volatile.Write(ref s_casingTable[pageNumber], casingTable); return casingTable; } }