diff --git a/mcs/class/Mono.Compiler/Mono.Compiler/RuntimeInformation.cs b/mcs/class/Mono.Compiler/Mono.Compiler/RuntimeInformation.cs index 083afba810ea..02b9c0395f47 100644 --- a/mcs/class/Mono.Compiler/Mono.Compiler/RuntimeInformation.cs +++ b/mcs/class/Mono.Compiler/Mono.Compiler/RuntimeInformation.cs @@ -1,15 +1,23 @@ using System; using System.Reflection; +using System.Runtime.CompilerServices; namespace Mono.Compiler { public class RuntimeInformation : IRuntimeInformation { - public InstalledRuntimeCode InstallCompilationResult (CompilationResult compilationResult, NativeCodeHandle codeHandle) { - throw new Exception ("not implemented yet"); + [MethodImplAttribute(MethodImplOptions.InternalCall)] + extern static InstalledRuntimeCode mono_install_compilation_result (int compilationResult, NativeCodeHandle codeHandle); + public InstalledRuntimeCode InstallCompilationResult (CompilationResult compilationResult, NativeCodeHandle codeHandle) { + return mono_install_compilation_result ((int) compilationResult, codeHandle); } + [MethodImplAttribute(MethodImplOptions.InternalCall)] + extern static int mono_execute_installed_method_2 (InstalledRuntimeCode irc, int arg0, int arg1); + public object ExecuteInstalledMethod (InstalledRuntimeCode irc, params object[] args) { - throw new Exception ("icall into runtime"); + if (args.Length == 2) + return mono_execute_installed_method_2 (irc, (int) args [0], (int) args [1]); + throw new Exception ("execute installed method: signature not supported yet"); } public ClassInfo GetClassInfoFor (string className) diff --git a/mcs/class/Mono.Compiler/Test/ICompilerInterfaceTest.cs b/mcs/class/Mono.Compiler/Test/ICompilerInterfaceTest.cs index ab007157e9aa..772b289e0658 100644 --- a/mcs/class/Mono.Compiler/Test/ICompilerInterfaceTest.cs +++ b/mcs/class/Mono.Compiler/Test/ICompilerInterfaceTest.cs @@ -33,7 +33,7 @@ public void TestAddMethod () { InstalledRuntimeCode irc = runtimeInfo.InstallCompilationResult (result, nativeCode); int addition = (int) runtimeInfo.ExecuteInstalledMethod (irc, 1, 2); - Assert.Equals (addition, 3); + Assert.AreEqual (addition, 3); } [Test] @@ -50,8 +50,7 @@ public unsafe void TestInstallCompilationResultAndExecute () { InstalledRuntimeCode irc = runtimeInfo.InstallCompilationResult (result, nativeCode); int addition = (int) runtimeInfo.ExecuteInstalledMethod (irc, 1, 2); - Assert.Equals (addition, 3); - + Assert.AreEqual (addition, 3); } [Test] @@ -96,7 +95,7 @@ public unsafe void TestSimpleRet () { compiler.CompileMethod (runtimeInfo, mi, CompilationFlags.None, out nativeCode); - Assert.True (*nativeCode.Blob == 0xc3); // 0xc3 is 'RET' in amd64 assembly + Assert.AreEqual (*nativeCode.Blob, (byte) 0xc3); // 0xc3 is 'RET' in amd64 assembly } } } diff --git a/mono/metadata/domain-internals.h b/mono/metadata/domain-internals.h index 2a961aa01039..b67fd41fa341 100644 --- a/mono/metadata/domain-internals.h +++ b/mono/metadata/domain-internals.h @@ -215,6 +215,7 @@ struct _MonoJitInfo { MonoImage *image; gpointer aot_info; gpointer tramp_info; + gpointer installed_runtime_code; // mjit } d; union { struct _MonoJitInfo *next_jit_code_hash; @@ -359,6 +360,7 @@ struct _MonoDomain { GHashTable *proxy_vtable_hash; /* Protected by 'jit_code_hash_lock' */ MonoInternalHashTable jit_code_hash; + MonoInternalHashTable mjit_code_hash; mono_mutex_t jit_code_hash_lock; int num_jit_info_table_duplicates; MonoJitInfoTable * diff --git a/mono/metadata/domain.c b/mono/metadata/domain.c index e6bfb6d6a923..5a268afcc2b7 100644 --- a/mono/metadata/domain.c +++ b/mono/metadata/domain.c @@ -429,6 +429,7 @@ mono_domain_create (void) domain->class_vtable_array = g_ptr_array_new (); domain->proxy_vtable_hash = g_hash_table_new ((GHashFunc)mono_ptrarray_hash, (GCompareFunc)mono_ptrarray_equal); mono_jit_code_hash_init (&domain->jit_code_hash); + mono_jit_code_hash_init (&domain->mjit_code_hash); domain->ldstr_table = mono_g_hash_table_new_type ((GHashFunc)mono_string_hash, (GCompareFunc)mono_string_equal, MONO_HASH_KEY_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, domain, "Domain String Pool Table"); domain->num_jit_info_table_duplicates = 0; domain->jit_info_table = mono_jit_info_table_new (domain); diff --git a/mono/mini/mini-runtime.c b/mono/mini/mini-runtime.c index e1939f49f508..9b94b641f742 100644 --- a/mono/mini/mini-runtime.c +++ b/mono/mini/mini-runtime.c @@ -4455,6 +4455,57 @@ mini_init (const char *filename, const char *runtime_version) return domain; } +struct _NativeCodeHandle { + MonoObject object; + gpointer blob; + gint64 length; +}; +typedef struct _NativeCodeHandle NativeCodeHandle; + +struct _InstalledRuntimeCode { + MonoObject object; +}; +typedef struct _InstalledRuntimeCode InstalledRuntimeCode; + + +static InstalledRuntimeCode* +ves_icall_mjit_install_compilation_result (int compilation_result, NativeCodeHandle *native_code) +{ + if (compilation_result != 0) { + g_printerr ("mjit_install: failed with %d\n", compilation_result); + return NULL; + } + + MonoDomain *domain = mono_domain_get (); + + // TODO: should it be a managed object? + InstalledRuntimeCode *key = mono_domain_alloc0 (domain, sizeof (InstalledRuntimeCode)); + + MonoJitInfo *jinfo = mono_domain_alloc0 (domain, MONO_SIZEOF_JIT_INFO); + // g_print ("reserving %d bytes code buffer\n", native_code->length); + jinfo->d.installed_runtime_code = key; + jinfo->code_start = mono_global_codeman_reserve (native_code->length); + jinfo->code_size = native_code->length; + // TODO: fill more metadata for MonoJitInfo* + + memcpy (jinfo->code_start, native_code->blob, native_code->length); + + mono_internal_hash_table_insert (&domain->mjit_code_hash, key, jinfo); + + return key; +} + +static int +ves_icall_mjit_execute_installed_method_2 (InstalledRuntimeCode *irc, int arg0, int arg1) +{ + MonoDomain *domain = mono_domain_get (); + MonoJitInfo *jinfo = mono_internal_hash_table_lookup (&domain->mjit_code_hash, irc); + + int (*f) (int, int) = jinfo->code_start; + + return f (arg0, arg1); +} + static void register_icalls (void) { @@ -4467,6 +4518,9 @@ register_icalls (void) mono_add_internal_call ("Mono.Runtime::mono_runtime_cleanup_handlers", mono_runtime_cleanup_handlers); + mono_add_internal_call ("Mono.Compiler.RuntimeInformation::mono_install_compilation_result", ves_icall_mjit_install_compilation_result); + mono_add_internal_call ("Mono.Compiler.RuntimeInformation::mono_execute_installed_method_2", ves_icall_mjit_execute_installed_method_2); + #if defined(HOST_ANDROID) || defined(TARGET_ANDROID) mono_add_internal_call ("System.Diagnostics.Debugger::Mono_UnhandledException_internal", mini_get_dbg_callbacks ()->unhandled_exception);