From ef2f785c9642cdf46db3d97ce9085327b98085bc Mon Sep 17 00:00:00 2001 From: =?utf8?q?=D0=AF=D1=80=D0=BE=D1=81=D0=BB=D0=B0=D0=B2=20=D0=AF=D0=BC?= =?utf8?q?=D1=89=D0=B8=D0=BA=D0=BE=D0=B2/Device=20Solutions=20Lab=20/SRR/E?= =?utf8?q?ngineer/=EC=82=BC=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Thu, 6 Jun 2019 17:59:36 +0300 Subject: [PATCH] C# .dll with code for type preloading (#57) * Preload common managed code * Tizen.Init.dll for type preloading and caller code --- Init/Init.cs | 185 ++++++++++++++++++++++ Init/Tizen.Init.csproj | 20 +++ NativeLauncher/launcher/dotnet/dotnet_launcher.cc | 29 ++++ NativeLauncher/launcher/dotnet/dotnet_launcher.h | 3 +- packaging/dotnet-launcher.spec | 9 ++ 5 files changed, 245 insertions(+), 1 deletion(-) create mode 100644 Init/Init.cs create mode 100644 Init/Tizen.Init.csproj diff --git a/Init/Init.cs b/Init/Init.cs new file mode 100644 index 0000000..5658226 --- /dev/null +++ b/Init/Init.cs @@ -0,0 +1,185 @@ +/* + * 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.Reflection; +using System.Runtime.Loader; +using System.IO; + +namespace Tizen.Init { + + class TypeLoader + { + static string[,] assem_type = new string[,] + { + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Box"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Button"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Check"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Color"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Conformant"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.DateTimeSelector"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.DisplayRotation"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.EdjeObject"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.EdjeObject+SignalData"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.EdjeTextPartObject"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Elementary"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Entry"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.EvasKeyEventArgs"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.EvasMap"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.EvasObject"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.FocusDirection"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.GenList"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.GestureLayer+GestureType"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.IInvalidatable"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Image"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.ItemObject+SignalData"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Label"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Layout"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Naviframe"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.NaviItem"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Point3D"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.ProgressBar"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Radio"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Rect"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Rectangle"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Scroller"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Size"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Slider"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Spinner"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Widget"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Window"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.WrapType"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "Interop"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.Wearable.dll", "ElmSharp.Wearable.CircleDateTimeSelector"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.Wearable.dll", "ElmSharp.Wearable.CircleGenList"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.Wearable.dll", "ElmSharp.Wearable.CircleScroller"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.Wearable.dll", "ElmSharp.Wearable.CircleSpinner"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.Wearable.dll", "ElmSharp.Wearable.ICircleWidget"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.Wearable.dll", "ElmSharp.Wearable.IRotaryActionWidget"}, + {"/usr/share/dotnet.tizen/framework/ElmSharp.Wearable.dll", "Interop"}, + {"/usr/share/dotnet.tizen/netcoreapp/System.IO.FileSystem.dll", "Interop"}, + {"/usr/share/dotnet.tizen/netcoreapp/System.IO.FileSystem.dll", ""}, + {"/usr/share/dotnet.tizen/netcoreapp/System.IO.FileSystem.dll", "System.IO.File"}, + {"/usr/share/dotnet.tizen/netcoreapp/System.Security.Cryptography.Algorithms.dll", "Interop"}, + {"/usr/share/dotnet.tizen/netcoreapp/System.Security.Cryptography.Algorithms.dll", "System.Security.Cryptography.MD5"}, + {"/usr/share/dotnet.tizen/netcoreapp/System.Collections.dll", ""}, + {"/usr/share/dotnet.tizen/netcoreapp/System.Collections.dll", "System.Collections.Generic.HashSet`1"}, + {"/usr/share/dotnet.tizen/netcoreapp/System.Collections.dll", "System.Collections.Generic.Queue`1"}, + {"/usr/share/dotnet.tizen/netcoreapp/System.Private.Uri.dll", ""}, + {"/usr/share/dotnet.tizen/netcoreapp/System.Private.Uri.dll", "System.Uri"}, + {"/usr/share/dotnet.tizen/netcoreapp/System.Private.Xml.dll", ""}, + {"/usr/share/dotnet.tizen/netcoreapp/System.Private.Xml.dll", "System.Xml.IXmlLineInfo"}, + {"/usr/share/dotnet.tizen/netcoreapp/System.Private.Xml.dll", "System.Xml.IXmlNamespaceResolver"}, + {"/usr/share/dotnet.tizen/netcoreapp/System.Runtime.dll", "System.Collections.Generic.ISet`1"}, + {"/usr/share/dotnet.tizen/netcoreapp/System.Runtime.dll", "System.Reflection.RuntimeReflectionExtensions"}, + {"/usr/share/dotnet.tizen/netcoreapp/System.ObjectModel.dll", "System.Collections.ObjectModel.ObservableCollection`1"}, + {"/usr/share/dotnet.tizen/netcoreapp/System.ObjectModel.dll", "System.Collections.Specialized.INotifyCollectionChanged"}, + {"/usr/share/dotnet.tizen/netcoreapp/System.ObjectModel.dll", "System.Collections.Specialized.NotifyCollectionChangedAction"}, + {"/usr/share/dotnet.tizen/netcoreapp/System.ObjectModel.dll", "System.Collections.Specialized.NotifyCollectionChangedEventArgs"}, + {"/usr/share/dotnet.tizen/netcoreapp/System.ObjectModel.dll", "System.Collections.Specialized.NotifyCollectionChangedEventHandler"}, + {"/usr/share/dotnet.tizen/netcoreapp/System.ObjectModel.dll", "System.ComponentModel.INotifyPropertyChanged"}, + {"/usr/share/dotnet.tizen/netcoreapp/System.ObjectModel.dll", "System.ComponentModel.PropertyChangedEventArgs"}, + {"/usr/share/dotnet.tizen/netcoreapp/System.ObjectModel.dll", "System.ComponentModel.PropertyChangedEventHandler"}, + {"/usr/share/dotnet.tizen/netcoreapp/System.ObjectModel.dll", "System.Windows.Input.ICommand"}, + {"/usr/share/dotnet.tizen/netcoreapp/System.ComponentModel.dll", "System.IServiceProvider"}, + {"/usr/share/dotnet.tizen/netcoreapp/System.Linq.dll", "System.Linq.Enumerable"}, + {"/usr/share/dotnet.tizen/netcoreapp/System.Linq.dll", "System.Linq.EnumerableSorter`1"}, + {"/usr/share/dotnet.tizen/netcoreapp/System.Linq.dll", "System.Linq.IIListProvider`1"}, + {"/usr/share/dotnet.tizen/netcoreapp/System.Linq.dll", "System.Linq.IOrderedEnumerable`1"}, + {"/usr/share/dotnet.tizen/netcoreapp/System.Linq.dll", "System.Linq.IPartition`1"}, + {"/usr/share/dotnet.tizen/netcoreapp/System.Linq.dll", "System.Linq.OrderedEnumerable`1"}, + {"/usr/share/dotnet.tizen/netcoreapp/System.Linq.Expressions.dll", "System.Linq.Expressions.ExpressionVisitor"}, + {"/usr/share/dotnet.tizen/netcoreapp/System.Security.Cryptography.Primitives.dll", "System.Security.Cryptography.HashAlgorithm"}, + {"/usr/share/dotnet.tizen/framework/Tizen.Applications.Common.dll", "Interop"}, + {"/usr/share/dotnet.tizen/framework/Tizen.Applications.Common.dll", "Tizen.Applications.Application"}, + {"/usr/share/dotnet.tizen/framework/Tizen.Applications.Common.dll", "Tizen.Applications.CoreApplication"}, + {"/usr/share/dotnet.tizen/framework/Tizen.Applications.Common.dll", "Tizen.Applications.CoreBackend.EventType"}, + {"/usr/share/dotnet.tizen/framework/Tizen.Applications.Common.dll", "Tizen.Applications.TizenSynchronizationContext"}, + {"/usr/share/dotnet.tizen/framework/Tizen.Applications.UI.dll", "Tizen.Applications.CoreUIApplication"}, + {"/usr/share/dotnet.tizen/framework/Tizen.Applications.UI.dll", "Interop"}, + {"/usr/share/dotnet.tizen/framework/Tizen.dll", "Interop"}, + {"/usr/share/dotnet.tizen/framework/Tizen.Log.dll", "Interop"}, + {"/usr/share/dotnet.tizen/framework/Tizen.Log.dll", "Tizen.Log"}, + {"/usr/share/dotnet.tizen/framework/Tizen.System.Information.dll", "Tizen.System.Information"} + }; + + static void PreloadEnd() + { + GC.Collect(); + GC.WaitForPendingFinalizers(); + } + + static int PreloadTypes() + { + string loaded_assem_name = new string(""); + Assembly loaded_assem = null; + for (int i = 0; i < assem_type.GetLength(0); i++) + { + if (assem_type[i,0] != loaded_assem_name) + { + loaded_assem_name = assem_type[i,0]; + loaded_assem = LoadAssembly(loaded_assem_name); + } + if (loaded_assem != null) + { + LoadType(loaded_assem, assem_type[i,1]); + } + } + PreloadEnd(); + + return 0; + } + static Assembly LoadAssembly(string path) + { + var context = AssemblyLoadContext.Default; + Assembly ret = null; + + try + { + if (File.Exists(path.Replace(".dll", ".ni.dll"))) + { + ret = context.LoadFromNativeImagePath(path.Replace(".dll", ".ni.dll"), path); + } else + {//by concept LoadFromNativeImagePath has to do fallbacks to + //properly passed IL asms, but it does not + ret = context.LoadFromAssemblyPath(path); + } + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + + return null; + } + + return ret; + } + static int LoadType(Assembly assem, string typeName) + { + try + { + var tp = assem.GetType(typeName); + } + catch + { + Console.WriteLine("Tizen.Init.TypeLoader.PreloadTypes can't load type " + typeName + " from assembly " + assem.ToString()); + return 1; + } + + return 0; + } + } +} diff --git a/Init/Tizen.Init.csproj b/Init/Tizen.Init.csproj new file mode 100644 index 0000000..6becf02 --- /dev/null +++ b/Init/Tizen.Init.csproj @@ -0,0 +1,20 @@ + + + netcoreapp2.1 + false + True + Release + + + + + + + + + + + + + + diff --git a/NativeLauncher/launcher/dotnet/dotnet_launcher.cc b/NativeLauncher/launcher/dotnet/dotnet_launcher.cc index 1464d9b..b76f54a 100644 --- a/NativeLauncher/launcher/dotnet/dotnet_launcher.cc +++ b/NativeLauncher/launcher/dotnet/dotnet_launcher.cc @@ -230,6 +230,30 @@ static std::u16string utf8ToUtf16(char* str) return convert.from_bytes(str); } +void CoreRuntime::preloadTypes() +{ + const static std::string initDllPath = "/usr/share/dotnet.tizen/framework/Tizen.Init.dll"; + if (!isFileExist(initDllPath)) { + _ERR("Failed to locate Tizen.Init.dll"); + return; + } + + typedef void (*InitDelegate)(); + InitDelegate initDelegate; + + int ret = createDelegate(__hostHandle, + __domainId, + "Tizen.Init", + "Tizen.Init.TypeLoader", + "PreloadTypes", + (void**)&initDelegate); + + if (ret < 0) { + _ERR("Failed to create delegate for PreloadTypes (0x%08x)", ret); + } else { + initDelegate(); + } +} CoreRuntime::CoreRuntime(const char* mode) : initializeClr(nullptr), @@ -381,6 +405,11 @@ int CoreRuntime::initialize(bool standalone) __initialized = true; + if (!standalone) + { + preloadTypes(); // Preload common managed code + } + _INFO("CoreRuntime initialize success"); return 0; diff --git a/NativeLauncher/launcher/dotnet/dotnet_launcher.h b/NativeLauncher/launcher/dotnet/dotnet_launcher.h index 62b1859..e230914 100644 --- a/NativeLauncher/launcher/dotnet/dotnet_launcher.h +++ b/NativeLauncher/launcher/dotnet/dotnet_launcher.h @@ -36,6 +36,7 @@ class CoreRuntime private: bool initializeCoreClr(const char* appId, const char* assemblyProbePaths, const char* pinvokeProbePaths, const char* tpaList); + void preloadTypes(); coreclr_initialize_ptr initializeClr; coreclr_execute_assembly_ptr executeAssembly; coreclr_shutdown_ptr shutdown; @@ -54,4 +55,4 @@ class CoreRuntime } // namespace runtime } // namespace tizen -#endif /* __DOTNET_LAUNCHER_H__ */ \ No newline at end of file +#endif /* __DOTNET_LAUNCHER_H__ */ diff --git a/packaging/dotnet-launcher.spec b/packaging/dotnet-launcher.spec index 74b03ba..77e641a 100644 --- a/packaging/dotnet-launcher.spec +++ b/packaging/dotnet-launcher.spec @@ -45,6 +45,7 @@ Requires(preun): /usr/bin/systemctl %define _loaderdir %{_prefix}/share/aul %define _device_api_dir %{dotnet_assembly_path} %define _runtime_dir /usr/share/dotnet.tizen/netcoreapp +%define _framework_dir /usr/share/dotnet.tizen/framework %define _install_mdplugin_dir /etc/package-manager/parserlib/metadata %define _native_lib_dir /usr/share/dotnet.tizen/lib @@ -77,6 +78,10 @@ export CXXFLAGS=$(echo $CXXFLAGS | sed -e 's/--target=i686/--target=i586/') %endif %endif +dotnet msbuild Init/Tizen.Init.csproj /t:clean +dotnet msbuild Init/Tizen.Init.csproj /t:restore /p:RestoreSources=/nuget +dotnet msbuild Init/Tizen.Init.csproj + cmake \ -DCMAKE_INSTALL_PREFIX=%{_prefix} \ %if 0%{?asan_enabled} @@ -102,6 +107,9 @@ make %{?jobs:-j%jobs} VERBOSE=1 %install rm -rf %{buildroot} %make_install +mkdir -p %{buildroot}%{_framework_dir} +mv Init/bin/Release/Tizen.Init.dll %{buildroot}%{_framework_dir} + mkdir -p %{buildroot}%{_native_lib_dir} ln -sf %{_libdir}/libsqlite3.so.0 %{buildroot}%{_native_lib_dir}/libsqlite3.so @@ -126,6 +134,7 @@ chsmack -t -a User::App::Shared /opt/etc/skel/.dotnet %{_libdir}/libdotnet_launcher_util.so %{_libdir}/libni_common.so /etc/tmpfiles.d/%{name}.conf +%{_framework_dir}/Tizen.Init.dll %files devel %manifest dotnet-launcher.manifest -- 2.7.4