From 5f4510d4db515b49015a961d335facd3e59b8614 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Fri, 5 Jan 2018 17:14:09 -0800 Subject: [PATCH] Simplify and unify EnumCalendars interop (#15762) Windows was not allocating GCHandles, switch Unix to do the same. --- .../System/Globalization/CalendarData.Unix.cs | 46 ++++++++-------------- .../System/Globalization/CalendarData.Windows.cs | 4 +- 2 files changed, 19 insertions(+), 31 deletions(-) diff --git a/src/mscorlib/shared/System/Globalization/CalendarData.Unix.cs b/src/mscorlib/shared/System/Globalization/CalendarData.Unix.cs index 3a8029d..4d1a63c 100644 --- a/src/mscorlib/shared/System/Globalization/CalendarData.Unix.cs +++ b/src/mscorlib/shared/System/Globalization/CalendarData.Unix.cs @@ -4,9 +4,9 @@ using System.Collections.Generic; using System.Diagnostics; -using System.Runtime.InteropServices; using System.Security; using System.Text; +using Internal.Runtime.CompilerServices; namespace System.Globalization { @@ -109,9 +109,10 @@ namespace System.Globalization { datePatterns = null; - CallbackContext callbackContext = new CallbackContext(); + EnumCalendarsData callbackContext = new EnumCalendarsData(); + callbackContext.Results = new List(); callbackContext.DisallowDuplicates = true; - bool result = EnumCalendarInfo(localeName, calendarId, dataType, callbackContext); + bool result = EnumCalendarInfo(localeName, calendarId, dataType, ref callbackContext); if (result) { List datePatternsList = callbackContext.Results; @@ -244,8 +245,9 @@ namespace System.Globalization { monthNames = null; - CallbackContext callbackContext = new CallbackContext(); - bool result = EnumCalendarInfo(localeName, calendarId, dataType, callbackContext); + EnumCalendarsData callbackContext = new EnumCalendarsData(); + callbackContext.Results = new List(); + bool result = EnumCalendarInfo(localeName, calendarId, dataType, ref callbackContext); if (result) { // the month-name arrays are expected to have 13 elements. If ICU only returns 12, add an @@ -280,8 +282,9 @@ namespace System.Globalization { calendarData = null; - CallbackContext callbackContext = new CallbackContext(); - bool result = EnumCalendarInfo(localeName, calendarId, dataType, callbackContext); + EnumCalendarsData callbackContext = new EnumCalendarsData(); + callbackContext.Results = new List(); + bool result = EnumCalendarInfo(localeName, calendarId, dataType, ref callbackContext); if (result) { calendarData = callbackContext.Results.ToArray(); @@ -290,24 +293,16 @@ namespace System.Globalization return result; } - private static bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, CallbackContext callbackContext) + private static unsafe bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, ref EnumCalendarsData callbackContext) { - GCHandle context = GCHandle.Alloc(callbackContext); - try - { - return Interop.GlobalizationInterop.EnumCalendarInfo(EnumCalendarInfoCallback, localeName, calendarId, dataType, (IntPtr)context); - } - finally - { - context.Free(); - } + return Interop.GlobalizationInterop.EnumCalendarInfo(EnumCalendarInfoCallback, localeName, calendarId, dataType, (IntPtr)Unsafe.AsPointer(ref callbackContext)); } - private static void EnumCalendarInfoCallback(string calendarString, IntPtr context) + private static unsafe void EnumCalendarInfoCallback(string calendarString, IntPtr context) { try { - CallbackContext callbackContext = (CallbackContext)((GCHandle)context).Target; + ref EnumCalendarsData callbackContext = ref Unsafe.As(ref *(byte*)context); if (callbackContext.DisallowDuplicates) { @@ -331,17 +326,10 @@ namespace System.Globalization } } - private class CallbackContext + private struct EnumCalendarsData { - private List _results = new List(); - - public CallbackContext() - { - } - - public List Results { get { return _results; } } - - public bool DisallowDuplicates { get; set; } + public List Results; + public bool DisallowDuplicates; } } } diff --git a/src/mscorlib/shared/System/Globalization/CalendarData.Windows.cs b/src/mscorlib/shared/System/Globalization/CalendarData.Windows.cs index a67761a..03f9088 100644 --- a/src/mscorlib/shared/System/Globalization/CalendarData.Windows.cs +++ b/src/mscorlib/shared/System/Globalization/CalendarData.Windows.cs @@ -274,7 +274,7 @@ namespace System.Globalization } // Context for EnumCalendarInfoExEx callback. - private class EnumData + private struct EnumData { public string userOverride; public List strings; @@ -427,7 +427,7 @@ namespace System.Globalization // // struct to help our calendar data enumaration callback // - private class EnumCalendarsData + private struct EnumCalendarsData { public int userOverride; // user override value (if found) public List calendars; // list of calendars found so far -- 2.7.4