/* * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; 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 Preload() { CheckAsciiCasing(); if (!Directory.Exists(preloadPath)) 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; // ex) 000.Tizen.preload / 0.Tizen.preload if (fileName.IndexOf('.') != 2) continue; string value = System.Environment.GetEnvironmentVariable("TIZEN_UIFW"); // if TIZEN_UIFW is not set, do not preload UI related dll if (value == null && (fileName.Contains("NUI") || fileName.Contains("ElmSharp") || fileName.Contains("XSF") )) continue; else if (value == "ElmSharp" && fileName.Contains("NUI")) continue; else if (value == "NUI" && (fileName.Contains("ElmSharp") || fileName.Contains("XSF"))) continue; try { Console.WriteLine("Start preload : " + fileName); BindingFlags bindingFlag = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; foreach (string line in File.ReadLines(path)) { if (line.StartsWith('#') || !line.Contains(".dll") || !line.Contains(' ')) continue; string[] getWord = line.Split(' '); if (getWord.Length != 2) continue; string assemblyStr = getWord[0].Replace(".dll", ""); string typenameStr = getWord[1]; string methodStr = ""; string parenthesis = "()"; if (line.Contains(parenthesis)) { string[] getMethod = typenameStr.Split('.'); methodStr = getMethod[getMethod.Length - 1].Replace(parenthesis, ""); typenameStr = typenameStr.Replace("." + methodStr + parenthesis, ""); } if (assemblyStr == "") { Console.WriteLine("[Warning] Skip the '" + line + "' in " + fileName); continue; } try { Assembly asm = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(assemblyStr)); if (asm == null) { Console.WriteLine("[Warning] Check the '" + line + "' in " + fileName); continue; } if (typenameStr != "" && !typenameStr.Contains(parenthesis)) { 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 { Console.WriteLine("[Error] Fail the '" + line + "' in " + fileName); } } } catch (IOException e) { Console.WriteLine(e.ToString()); Console.WriteLine("[Error] Failed to open file : " + fileName); } } GC.Collect(); GC.WaitForPendingFinalizers(); Profiler.SetCandidateProcessProfile(); } } }