diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/MethodTable.Runtime.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/MethodTable.Runtime.cs index 899ac448d5f9d8..c0c196713aa846 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/MethodTable.Runtime.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/MethodTable.Runtime.cs @@ -37,7 +37,7 @@ internal bool IsEnum // Generic type definitions that return true for IsPrimitive are type definitions of generic enums. // Otherwise check the base type. - return IsPrimitive && (IsGenericTypeDefinition || NonArrayBaseType == MethodTable.Of()); + return IsPrimitive && (IsGenericTypeDefinition || NonArrayBaseType != MethodTable.Of()); } } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.NativeAot.cs index 6f6aec5df683aa..3f14becf5ee7cb 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.NativeAot.cs @@ -764,7 +764,7 @@ public static long GetTotalAllocatedBytes(bool precise = false) /// Gets garbage collection memory information. /// An object that contains information about the garbage collector's memory usage. - public static GCMemoryInfo GetGCMemoryInfo() => GetGCMemoryInfo(GCKind.Any); + public static GCMemoryInfo GetGCMemoryInfo() => GetGCMemoryInfoUnchecked(GCKind.Any); /// Gets garbage collection memory information. /// The kind of collection for which to retrieve memory information. @@ -780,6 +780,11 @@ public static GCMemoryInfo GetGCMemoryInfo(GCKind kind) GCKind.Background)); } + return GetGCMemoryInfoUnchecked(kind); + } + + private static GCMemoryInfo GetGCMemoryInfoUnchecked(GCKind kind) + { var data = new GCMemoryInfoData(); RuntimeImports.RhGetMemoryInfo(ref data.GetRawData(), kind); return new GCMemoryInfo(data); diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Thread.NativeAot.Windows.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Thread.NativeAot.Windows.cs index 12a2273eddf605..f01fe0f86f38f7 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Thread.NativeAot.Windows.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Thread.NativeAot.Windows.cs @@ -289,7 +289,14 @@ private bool SetApartmentStateUnchecked(ApartmentState state, bool throwOnError) { if (throwOnError) { - string msg = SR.Format(SR.Thread_ApartmentState_ChangeFailed, retState); + // NOTE: We do the enum stringification manually to avoid introducing a dependency + // on enum stringification in small apps. We set apartment state in the startup path. + string msg = SR.Format(SR.Thread_ApartmentState_ChangeFailed, retState switch + { + ApartmentState.MTA => "MTA", + ApartmentState.STA => "STA", + _ => "Unknown" + }); throw new InvalidOperationException(msg); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs index e52739208f392c..9a870579f94be7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs @@ -625,15 +625,11 @@ private static CultureData CreateCultureWithInvariantData() invariant._iFirstDayOfWeek = 0; // first day of week invariant._iFirstWeekOfYear = 0; // first week of year - // all available calendar type(s). The first one is the default calendar - invariant._waCalendars = [CalendarId.GREGORIAN]; - - if (!GlobalizationMode.InvariantNoLoad) - { - // Store for specific data about each calendar - invariant._calendars = new CalendarData[CalendarData.MAX_CALENDARS]; - invariant._calendars[0] = CalendarData.Invariant; - } + // Calendar information is expensive size-wise, especially for AOT. + // CalendarData.Invariant is special cased in _waCalendars and _calendars + // accessors and gets initialized lazily. + // invariant._waCalendars + // invariant._calendars // Text information invariant._iReadingLayout = 0; @@ -1647,61 +1643,68 @@ internal CalendarId[] CalendarIds { get { - if (_waCalendars == null && !GlobalizationMode.Invariant) + if (_waCalendars == null) { - // We pass in an array of ints, and native side fills it up with count calendars. - // We then have to copy that list to a new array of the right size. - // Default calendar should be first - CalendarId[] calendars = new CalendarId[23]; - Debug.Assert(_sWindowsName != null, "[CultureData.CalendarIds] Expected _sWindowsName to be populated by already"); - - int count = CalendarData.GetCalendarsCore(_sWindowsName, _bUseOverrides, calendars); - - // See if we had a calendar to add. - if (count == 0) + if (GlobalizationMode.Invariant || IsInvariantCulture) { - // Failed for some reason, just grab Gregorian from Invariant - _waCalendars = Invariant._waCalendars!; + // We do this lazily as opposed in CreateCultureWithInvariantData to avoid introducing + // enum arrays into apps that otherwise wouldn't have them. This helps with size in AOT. + _waCalendars = [CalendarId.GREGORIAN]; } else { - // The OS may not return calendar 4 for zh-TW, but we've always allowed it. - // TODO: Is this hack necessary long-term? - if (_sWindowsName == "zh-TW") - { - bool found = false; + // We pass in an array of ints, and native side fills it up with count calendars. + // We then have to copy that list to a new array of the right size. + // Default calendar should be first + CalendarId[] calendars = new CalendarId[23]; + Debug.Assert(_sWindowsName != null, "[CultureData.CalendarIds] Expected _sWindowsName to be populated by already"); + + int count = CalendarData.GetCalendarsCore(_sWindowsName, _bUseOverrides, calendars); - // Do we need to insert calendar 4? - for (int i = 0; i < count; i++) + // See if we had a calendar to add. + if (count == 0) + { + // Failed for some reason, just use Gregorian + _waCalendars = Invariant.CalendarIds; + } + else + { + // The OS may not return calendar 4 for zh-TW, but we've always allowed it. + // TODO: Is this hack necessary long-term? + if (_sWindowsName == "zh-TW") { - // Stop if we found calendar four - if (calendars[i] == CalendarId.TAIWAN) + bool found = false; + + // Do we need to insert calendar 4? + for (int i = 0; i < count; i++) { - found = true; - break; + // Stop if we found calendar four + if (calendars[i] == CalendarId.TAIWAN) + { + found = true; + break; + } } - } - // If not found then insert it - if (!found) - { - // Insert it as the 2nd calendar - count++; - // Copy them from the 2nd position to the end, -1 for skipping 1st, -1 for one being added. - Array.Copy(calendars, 1, calendars, 2, 23 - 1 - 1); - calendars[1] = CalendarId.TAIWAN; + // If not found then insert it + if (!found) + { + // Insert it as the 2nd calendar + count++; + // Copy them from the 2nd position to the end, -1 for skipping 1st, -1 for one being added. + Array.Copy(calendars, 1, calendars, 2, 23 - 1 - 1); + calendars[1] = CalendarId.TAIWAN; + } } - } - - // It worked, remember the list - CalendarId[] temp = new CalendarId[count]; - Array.Copy(calendars, temp, count); - _waCalendars = temp; + // It worked, remember the list + CalendarId[] temp = new CalendarId[count]; + Array.Copy(calendars, temp, count); + _waCalendars = temp; + } } } - - return _waCalendars!; + return _waCalendars; } } @@ -1737,8 +1740,17 @@ internal CalendarData GetCalendar(CalendarId calendarId) // Make sure that calendar has data if (calendarData == null) { - Debug.Assert(_sWindowsName != null, "[CultureData.GetCalendar] Expected _sWindowsName to be populated by already"); - calendarData = new CalendarData(_sWindowsName, calendarId, _bUseOverrides); + if (calendarIndex == 0 && IsInvariantCulture) + { + // We do this lazily as opposed in CreateCultureWithInvariantData to avoid introducing + // invariant calendar data into apps that don't even need calendar. + calendarData = CalendarData.Invariant; + } + else + { + Debug.Assert(_sWindowsName != null, "[CultureData.GetCalendar] Expected _sWindowsName to be populated by already"); + calendarData = new CalendarData(_sWindowsName, calendarId, _bUseOverrides); + } _calendars[calendarIndex] = calendarData; }