C# .dll with code for type preloading (#57)
authorЯрослав Ямщиков/Device Solutions Lab /SRR/Engineer/삼성전자 <y.yamshchiko@samsung.com>
Thu, 6 Jun 2019 14:59:36 +0000 (17:59 +0300)
committerAlexander Soldatov/AI Compiler Lab /SRR/Staff Engineer/삼성전자 <soldatov.a@samsung.com>
Thu, 6 Jun 2019 14:59:36 +0000 (17:59 +0300)
* Preload common managed code
* Tizen.Init.dll for type preloading and caller code

Init/Init.cs [new file with mode: 0644]
Init/Tizen.Init.csproj [new file with mode: 0644]
NativeLauncher/launcher/dotnet/dotnet_launcher.cc
NativeLauncher/launcher/dotnet/dotnet_launcher.h
packaging/dotnet-launcher.spec

diff --git a/Init/Init.cs b/Init/Init.cs
new file mode 100644 (file)
index 0000000..5658226
--- /dev/null
@@ -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", "<PrivateImplementationDetails>"},
+            {"/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", "<PrivateImplementationDetails>"},
+            {"/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", "<PrivateImplementationDetails>"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.Private.Uri.dll", "System.Uri"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.Private.Xml.dll", "<PrivateImplementationDetails>"},
+            {"/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 (file)
index 0000000..6becf02
--- /dev/null
@@ -0,0 +1,20 @@
+<Project Sdk="Microsoft.NET.Sdk">
+    <PropertyGroup>
+           <TargetFramework>netcoreapp2.1</TargetFramework>
+           <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
+           <NoWin32Manifest>True</NoWin32Manifest>
+           <Configuration>Release</Configuration>
+    </PropertyGroup>
+
+    <ItemGroup>
+       <Reference Include="System.Runtime">
+       </Reference>
+       <Reference Include="System.Runtime.Loader">
+       </Reference>
+       <Reference Include="System.Console">
+       </Reference>
+       <Reference Include="System.IO.FileSystem">
+       </Reference>
+    </ItemGroup>
+
+</Project>
index 1464d9b..b76f54a 100644 (file)
@@ -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;
index 62b1859..e230914 100644 (file)
@@ -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__ */
index 74b03ba..77e641a 100644 (file)
@@ -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