using System.IO;
using System.Reflection;
using System.Runtime.Loader;
+using System.Globalization;
+using System.Runtime.CompilerServices;
namespace Tizen.Runtime
{
public class Preloader
{
const string preloadPath = "/usr/share/dotnet.tizen/preload/";
+
+ // If current culture's casing for ASCII is the same as invariant, it can take a fast path
+ // than calling out to the OS for culture-aware casing.
+ // However, in certain languages, the following function may be significantly slowed down.
+ // To avoid that kind situation, call it in advance on the candidate process.
+ [MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)]
+ private static void CheckAsciiCasing()
+ {
+ _ = CultureInfo.CurrentCulture.CompareInfo.Compare("abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", CompareOptions.IgnoreCase);
+ _ = "abc".ToUpper().ToLower();
+ }
+
+ public static void CoreclrPreload()
+ {
+ CheckAsciiCasing();
+ }
+
public static void Preload()
{
+ CheckAsciiCasing();
+
+ if (!Directory.Exists(preloadPath))
+ return;
+
+ // If TIZEN_UIFW is not set or NUI, do not preload UI related dll
+ string uifw = System.Environment.GetEnvironmentVariable("TIZEN_UIFW");
+ if (uifw == null || uifw != "NUI")
+ return;
+
string[] paths = Directory.GetFiles(preloadPath, "*.preload");
Array.Sort(paths);
foreach (string path in paths)
{
string fileName = Path.GetFileName(path);
+
+ // GetFileName() can return NULL
+ if (fileName == null)
+ continue;
+
// ex) Tizen.preload / 0A.Tizen.preload / A0.Tizen.preload / .0.Tizen.preload / .00.Tizen.preload
if (!char.IsNumber(fileName, 0) || !char.IsNumber(fileName, 1))
continue;
if (fileName.IndexOf('.') != 2)
continue;
+ // TIZEN_UIFW only set NUI
+ if (fileName.Contains("ElmSharp") || fileName.Contains("XSF"))
+ continue;
+
try
{
- Console.WriteLine("Start preload : " + fileName);
+ Console.WriteLine("UIFW: " + uifw + " Start preload : " + fileName);
BindingFlags bindingFlag = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
foreach (string line in File.ReadLines(path))
{
typenameStr = typenameStr.Replace("." + methodStr + parenthesis, "");
}
- if (assemblyStr == "" || typenameStr == "" || typenameStr.Contains(parenthesis))
+ if (assemblyStr == "")
{
Console.WriteLine("[Warning] Skip the '" + line + "' in " + fileName);
continue;
try
{
Assembly asm = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(assemblyStr));
- Type type = asm.GetType(typenameStr);
- if (type == null)
+ if (asm == null)
+ {
Console.WriteLine("[Warning] Check the '" + line + "' in " + fileName);
+ continue;
+ }
- if (methodStr != "")
+ if (typenameStr != "" && !typenameStr.Contains(parenthesis))
{
- MethodInfo method = type.GetMethod(methodStr, bindingFlag);
- method.Invoke(null, null);
+ Type type = asm.GetType(typenameStr);
+ if (type == null)
+ {
+ Console.WriteLine("[Warning] Check the '" + line + "' in " + fileName);
+ continue;
+ }
+
+ if (methodStr != "")
+ {
+ MethodInfo method = type.GetMethod(methodStr, bindingFlag);
+ if (method == null)
+ {
+ Console.WriteLine("[Warning] Check the '" + line + "' in " + fileName);
+ continue;
+ }
+ method.Invoke(null, null);
+ }
}
}
catch
GC.Collect();
GC.WaitForPendingFinalizers();
+
+ Profiler.SetCandidateProcessProfile();
}
}
}