Skip to content

Commit

Permalink
[Mono.Compiler] add mini-runtime support to install and execute metho…
Browse files Browse the repository at this point in the history
…ds coming from managed code

tailored to `int function (int, int)`, but it's a start :-)
  • Loading branch information
lewurm committed Jul 23, 2018
1 parent 8cc5ba5 commit 391b778
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 7 deletions.
14 changes: 11 additions & 3 deletions mcs/class/Mono.Compiler/Mono.Compiler/RuntimeInformation.cs
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
7 changes: 3 additions & 4 deletions mcs/class/Mono.Compiler/Test/ICompilerInterfaceTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -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]
Expand Down Expand Up @@ -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
}
}
}
2 changes: 2 additions & 0 deletions mono/metadata/domain-internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 *
Expand Down
1 change: 1 addition & 0 deletions mono/metadata/domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
54 changes: 54 additions & 0 deletions mono/mini/mini-runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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);
Expand Down

0 comments on commit 391b778

Please sign in to comment.