Avoid heap allocating in char.ConvertFromUtf32 (dotnet/coreclr#6141)
authorJames Ko <jamesqko@gmail.com>
Thu, 7 Jul 2016 10:41:09 +0000 (06:41 -0400)
committerJan Kotas <jkotas@microsoft.com>
Thu, 7 Jul 2016 10:41:09 +0000 (12:41 +0200)
Commit migrated from https://github.com/dotnet/coreclr/commit/ebbff97a9712ae1e625a9a7c26586f8f21070b5c

src/coreclr/src/mscorlib/src/System/Char.cs

index 9904f84..c7fd4b3 100644 (file)
@@ -914,6 +914,7 @@ namespace System {
         ** Convert an UTF32 value into a surrogate pair.
         ==============================================================================*/
         
+        [System.Security.SecuritySafeCritical]
         public static String ConvertFromUtf32(int utf32)
         {
             // For UTF32 values from U+00D800 ~ U+00DFFF, we should throw.  They
@@ -927,12 +928,17 @@ namespace System {
                 // This is a BMP character.
                 return (Char.ToString((char)utf32));
             }
-            // This is a sumplementary character.  Convert it to a surrogate pair in UTF-16.
-            utf32 -= UNICODE_PLANE01_START;
-            char[] surrogate = new char[2];
-            surrogate[0] = (char)((utf32 / 0x400) + (int)CharUnicodeInfo.HIGH_SURROGATE_START);
-            surrogate[1] = (char)((utf32 % 0x400) + (int)CharUnicodeInfo.LOW_SURROGATE_START);
-            return (new String(surrogate));
+
+            unsafe
+            {
+                // This is a supplementary character.  Convert it to a surrogate pair in UTF-16.
+                utf32 -= UNICODE_PLANE01_START;
+                uint surrogate = 0; // allocate 2 chars worth of stack space
+                char* address = (char*)&surrogate;
+                address[0] = (char)((utf32 / 0x400) + (int)CharUnicodeInfo.HIGH_SURROGATE_START);
+                address[1] = (char)((utf32 % 0x400) + (int)CharUnicodeInfo.LOW_SURROGATE_START);
+                return new string(address, 0, 2);
+            }
         }