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(Path.GetFileName(path), 0) || !char.IsNumber(Path.GetFileName(path), 1))
+ if (!char.IsNumber(fileName, 0) || !char.IsNumber(fileName, 1))
continue;
// ex) 000.Tizen.preload / 0.Tizen.preload
- if (Path.GetFileName(path).IndexOf('.') != 2)
+ if (fileName.IndexOf('.') != 2)
+ continue;
+
+ // TIZEN_UIFW only set NUI
+ if (fileName.Contains("ElmSharp") || fileName.Contains("XSF"))
continue;
try
{
+ 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, "");
}
- try
+ if (assemblyStr == "")
{
- if (assemblyStr == "")
- continue;
+ Console.WriteLine("[Warning] Skip the '" + line + "' in " + fileName);
+ continue;
+ }
+ try
+ {
Assembly asm = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(assemblyStr));
- if (asm == null || typenameStr == "")
+ if (asm == null)
+ {
+ Console.WriteLine("[Warning] Check the '" + line + "' in " + fileName);
continue;
+ }
- Type type = asm.GetType(typenameStr);
- if (type == null || methodStr == "")
- continue;
-
- MethodInfo method = type.GetMethod(methodStr, bindingFlag);
- if (method == null)
- continue;
+ if (typenameStr != "" && !typenameStr.Contains(parenthesis))
+ {
+ Type type = asm.GetType(typenameStr);
+ if (type == null)
+ {
+ Console.WriteLine("[Warning] Check the '" + line + "' in " + fileName);
+ continue;
+ }
- method.Invoke(null, null);
+ 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 (Exception e)
+ catch
{
- Console.WriteLine(e.ToString());
- Console.WriteLine("[ERROR] Failed to '" + line + "' preload");
+ Console.WriteLine("[Error] Fail the '" + line + "' in " + fileName);
}
}
}
catch (IOException e)
{
Console.WriteLine(e.ToString());
- Console.WriteLine("[ERROR] Failed to " + path + " file open");
- }
- finally
- {
- Console.WriteLine("Success to preload : " + path);
+ Console.WriteLine("[Error] Failed to open file : " + fileName);
}
}
GC.Collect();
GC.WaitForPendingFinalizers();
+
+ Profiler.SetCandidateProcessProfile();
}
}
}