Skip to content

Commit

Permalink
[mjit] Add tests for MiniCompiler (mono#19)
Browse files Browse the repository at this point in the history
* [mjit] Store opt differently for MiniCompiler

* [mjit] Add tests for MiniCompiler
  • Loading branch information
luhenry committed Jul 25, 2018
1 parent fe15401 commit 018f498
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 58 deletions.
10 changes: 3 additions & 7 deletions mcs/class/Mono.Compiler/Mini/MiniCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,17 @@

namespace Mono.Compiler
{
internal unsafe class MiniCompiler : ICompiler
public unsafe class MiniCompiler : ICompiler
{
public CompilationResult CompileMethod (IRuntimeInformation runtimeInfo, MethodInfo methodInfo, CompilationFlags flags, out NativeCodeHandle nativeCode)
{
byte *code = CompileMethod(methodInfo.MethodHandle, methodInfo.Flags, out long codeLength);
if ((IntPtr) code == IntPtr.Zero) {
nativeCode = default(NativeCodeHandle);
if (!CompileMethod(methodInfo.RuntimeMethodHandle, (int) flags, out nativeCode))
return CompilationResult.InternalError;
}

nativeCode = new NativeCodeHandle(code, codeLength);
return CompilationResult.Ok;
}

[MethodImpl (MethodImplOptions.InternalCall)]
unsafe static extern byte* CompileMethod(IntPtr method, int flags, out long codeLength);
static extern bool CompileMethod(RuntimeMethodHandle runtimeMethodHandle, int flags, out NativeCodeHandle nativeCode);
}
}
12 changes: 10 additions & 2 deletions mcs/class/Mono.Compiler/Mono.Compiler/InstalledRuntimeCode.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
namespace Mono.Compiler {
public class InstalledRuntimeCode {

using System;

namespace Mono.Compiler
{
public struct InstalledRuntimeCode
{
#pragma warning disable 169
IntPtr handle; /* This is the actual pointer to the domain-allocated InstalledRuntimeCode */
#pragma warning restore 169
}
}
22 changes: 10 additions & 12 deletions mcs/class/Mono.Compiler/Mono.Compiler/MethodInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,22 @@ public class MethodInfo
public ClassInfo ClassInfo { get; }
public string Name { get; }
public MethodBody Body { get; }
/* TODO: unify with MethodHandle. This is a MonoReflectionMethod in C */
public RuntimeMethodHandle RuntimeMethodHandle { get; }

internal MethodInfo (ClassInfo ci, string name, MethodBody body, RuntimeMethodHandle runtimeMethodHandle) {
/* this is a MonoMethod in C */
internal RuntimeMethodHandle RuntimeMethodHandle { get; }

public MethodInfo (ClassInfo ci, string name, MethodBody body, RuntimeMethodHandle runtimeMethodHandle)
: this (runtimeMethodHandle)
{
ClassInfo = ci;
Name = name;
Body = body;
RuntimeMethodHandle = runtimeMethodHandle;
}

/* Used only for MiniCompiler. This should be merged with the above constructor. */
/* this is a MonoMethod in C */
internal IntPtr MethodHandle { get; }
internal int Flags { get; }

internal MethodInfo (IntPtr runtimeMethodHandle, int flags) {
MethodHandle = runtimeMethodHandle;
Flags = flags;
/* Used by MiniCompiler */
public MethodInfo (RuntimeMethodHandle runtimeMethodHandle)
{
RuntimeMethodHandle = runtimeMethodHandle;
}
}
}
4 changes: 4 additions & 0 deletions mcs/class/Mono.Compiler/Mono.Compiler/NativeCodeHandle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ public unsafe struct NativeCodeHandle
get { return blob; }
}

public long Length {
get { return length; }
}

public NativeCodeHandle (byte *codeBlob, long codeLength) {
blob = codeBlob;
length = codeLength;
Expand Down
1 change: 1 addition & 0 deletions mcs/class/Mono.Compiler/Mono.Compiler_test.dll.sources
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
ICompilerInterfaceTest.cs
MiniCompilerTest.cs
75 changes: 75 additions & 0 deletions mcs/class/Mono.Compiler/Test/MiniCompilerTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using System;
using NUnit.Framework;
using Mono.Compiler;

namespace MonoTests.Mono.Compiler
{
[TestFixture]
public class MiniCompilerTests
{
IRuntimeInformation runtimeInfo = null;
ICompiler compiler = null;

[TestFixtureSetUp]
public void Init () {
runtimeInfo = new RuntimeInformation ();
compiler = new MiniCompiler ();
}

public static void EmptyMethod () {
return;
}

public static int AddMethod (int a, int b) {
return a + b;
}

public static int AddMethod3 (int a, int b, int c) {
return a + b + c;
}

[Test]
public unsafe void TestEmptyMethod ()
{
MethodInfo methodInfo = new MethodInfo(this.GetType().GetMethod("EmptyMethod").MethodHandle);

CompilationResult result = compiler.CompileMethod (runtimeInfo, methodInfo, CompilationFlags.None, out NativeCodeHandle nativeCode);
Assert.AreEqual(result, CompilationResult.Ok);
Assert.AreNotEqual((IntPtr)nativeCode.Blob, IntPtr.Zero);
// AssertHelper.Greater(nativeCode.Length, 0);

InstalledRuntimeCode irc = runtimeInfo.InstallCompilationResult (result, methodInfo, nativeCode);
runtimeInfo.ExecuteInstalledMethod (irc);
}

[Test]
public unsafe void TestAddMethod ()
{
MethodInfo methodInfo = new MethodInfo(this.GetType().GetMethod("AddMethod").MethodHandle);

CompilationResult result = compiler.CompileMethod (runtimeInfo, methodInfo, CompilationFlags.None, out NativeCodeHandle nativeCode);
Assert.AreEqual(result, CompilationResult.Ok);
Assert.AreNotEqual((IntPtr)nativeCode.Blob, IntPtr.Zero);
// AssertHelper.Greater(nativeCode.Length, 0);

InstalledRuntimeCode irc = runtimeInfo.InstallCompilationResult (result, methodInfo, nativeCode);
int addition = (int) runtimeInfo.ExecuteInstalledMethod (irc, 1, 2);
Assert.AreEqual (addition, 3);
}

[Test]
public unsafe void TestAddMethod3 ()
{
MethodInfo methodInfo = new MethodInfo(this.GetType().GetMethod("AddMethod3").MethodHandle);

CompilationResult result = compiler.CompileMethod (runtimeInfo, methodInfo, CompilationFlags.None, out NativeCodeHandle nativeCode);
Assert.AreEqual(result, CompilationResult.Ok);
Assert.AreNotEqual((IntPtr)nativeCode.Blob, IntPtr.Zero);
// AssertHelper.Greater(nativeCode.Length, 0);

InstalledRuntimeCode irc = runtimeInfo.InstallCompilationResult (result, methodInfo, nativeCode);
int addition = (int) runtimeInfo.ExecuteInstalledMethod (irc, 1, 2, 3);
Assert.AreEqual (addition, 6);
}
}
}
60 changes: 30 additions & 30 deletions mono/mini/mini-runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -4489,7 +4489,7 @@ mjit_initialize (void)

g_assert (MethodInfo_klass);

MethodInfo_ctor_method = mono_class_get_method_from_name_checked (MethodInfo_klass, ".ctor", 2, 0, error);
MethodInfo_ctor_method = mono_class_get_method_from_name_checked (MethodInfo_klass, ".ctor", 1, 0, error);
mono_error_assert_ok (error);

g_assert (MethodInfo_ctor_method);
Expand All @@ -4507,19 +4507,19 @@ mjit_initialize (void)
mono_assembly_name_free (assembly_name);
}

typedef struct _NativeCodeHandle {
gpointer blob;
gint64 length;
} NativeCodeHandle;

static gpointer
compile_method_inner (MonoMethod *method, MonoDomain *target_domain, gint32 opt, MonoError *error)
{
if (!g_hasenv("MONO_MJIT"))
return mono_jit_compile_method_inner (method, target_domain, opt, error);

// g_printerr("%s: klass = %s%s%s, method = %s\n",
// __func__, (m_class_get_name_space(method->klass) && m_class_get_name_space(method->klass)[0] != '\0') ? m_class_get_name_space(method->klass) : "",
// (m_class_get_name_space(method->klass) && m_class_get_name_space(method->klass)[0] != '\0') ? "." : "", m_class_get_name (method->klass), method->name);
return mono_jit_compile_method_inner (method, target_domain, opt, NULL, error);

MonoObject *compiler, *method_info, *ret;
gint32 flags;
struct { gpointer code; gint64 code_length; } native_code;
NativeCodeHandle native_code;
gpointer params[4];

mono_lazy_initialize (&mjit_initialized, mjit_initialize);
Expand All @@ -4530,7 +4530,6 @@ compile_method_inner (MonoMethod *method, MonoDomain *target_domain, gint32 opt,

/* Invoke methodInfo..ctor */
params [0] = &method;
params [1] = &opt;
mono_runtime_invoke_interpreter (MethodInfo_ctor_method, method_info, params, error);
return_val_if_nok (error, NULL);

Expand All @@ -4539,10 +4538,9 @@ compile_method_inner (MonoMethod *method, MonoDomain *target_domain, gint32 opt,
return_val_if_nok (error, NULL);

/* Invoke compiler.CompileMethod */
flags = 0;
params[0] = NULL;
params[1] = method_info;
params[2] = &flags;
params[2] = &opt;
params[3] = &native_code;
ret = mono_runtime_invoke_interpreter (ICompiler_CompileMethod_method, compiler, params, error);
return_val_if_nok (error, NULL);
Expand All @@ -4552,30 +4550,32 @@ compile_method_inner (MonoMethod *method, MonoDomain *target_domain, gint32 opt,
return NULL;
}

// g_printerr("%s: klass = %s%s%s, method = %s -> native_code.code = %p, native_code.codeLength = %lld\n",
// __func__, (m_class_get_name_space(method->klass) && m_class_get_name_space(method->klass)[0] != '\0') ? m_class_get_name_space(method->klass) : "",
// (m_class_get_name_space(method->klass) && m_class_get_name_space(method->klass)[0] != '\0') ? "." : "", m_class_get_name (method->klass), method->name,
// native_code.code, native_code.code_length);

return native_code.code;
return native_code.blob;
}

static gpointer
ves_icall_Mono_Compiler_MiniCompiler_CompileMethod (MonoMethod *method, gint32 opt, MonoError *error)
static MonoBoolean
ves_icall_Mono_Compiler_MiniCompiler_CompileMethod (MonoMethod *method, gint32 opt, NativeCodeHandle *native_code)
{
return mono_jit_compile_method_inner (method, mono_domain_get (), opt, error);
}
ERROR_DECL(error);

struct _NativeCodeHandle {
gpointer blob;
gint64 length;
};
typedef struct _NativeCodeHandle NativeCodeHandle;
// g_printerr("%s: method = %s%s%s:%s (%p)\n",
// __func__, (m_class_get_name_space(method->klass) && m_class_get_name_space(method->klass)[0] != '\0') ? m_class_get_name_space(method->klass) : "",
// (m_class_get_name_space(method->klass) && m_class_get_name_space(method->klass)[0] != '\0') ? "." : "", m_class_get_name (method->klass), method->name, method);

struct _InstalledRuntimeCode {
MonoObject object;
};
typedef struct _InstalledRuntimeCode InstalledRuntimeCode;
native_code->blob = mono_jit_compile_method_inner (method, mono_domain_get (), opt, &native_code->length, error);
mono_error_set_pending_exception (error);

// g_printerr("%s: method = %s%s%s:%s (%p) -> native_code.blob = %p, native_code.length = %lld\n",
// __func__, (m_class_get_name_space(method->klass) && m_class_get_name_space(method->klass)[0] != '\0') ? m_class_get_name_space(method->klass) : "",
// (m_class_get_name_space(method->klass) && m_class_get_name_space(method->klass)[0] != '\0') ? "." : "", m_class_get_name (method->klass), method->name, method,
// native_code->blob, native_code->length);

return native_code->blob != NULL;
}

typedef struct _InstalledRuntimeCode {
MonoJitInfo *jinfo;
} InstalledRuntimeCode;

static InstalledRuntimeCode*
ves_icall_mjit_install_compilation_result (int compilation_result, MonoMethod *method, NativeCodeHandle native_code)
Expand Down
30 changes: 24 additions & 6 deletions mono/mini/mini.c
Original file line number Diff line number Diff line change
Expand Up @@ -4016,7 +4016,7 @@ mono_update_jit_stats (MonoCompile *cfg)
* Main entry point for the JIT.
*/
gpointer
mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, gint32 opt, MonoError *error)
mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, gint32 opt, gint64 *code_length, MonoError *error)
{
MonoCompile *cfg;
gpointer code = NULL;
Expand All @@ -4028,6 +4028,9 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, gi

error_init (error);

if (code_length)
*code_length = 0;

jit_timer = mono_time_track_start ();
cfg = mini_method_compile (method, opt, target_domain, JIT_FLAG_RUN_CCTORS, 0, -1);
gdouble jit_time = 0.0;
Expand Down Expand Up @@ -4131,8 +4134,6 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, gi
*/
mono_update_jit_stats (cfg);

mono_destroy_compile (cfg);

#ifndef DISABLE_JIT
/* Update llvm callees */
if (domain_jit_info (target_domain)->llvm_jit_callees) {
Expand All @@ -4150,11 +4151,16 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, gi
#endif
mono_domain_unlock (target_domain);

if (!mono_error_ok (error))
if (!mono_error_ok (error)) {
mono_destroy_compile (cfg);
return NULL;
}

vtable = mono_class_vtable_checked (target_domain, method->klass, error);
return_val_if_nok (error, NULL);
if (!mono_error_ok (error)) {
mono_destroy_compile (cfg);
return NULL;
}

if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
if (mono_marshal_method_from_wrapper (method)) {
Expand All @@ -4170,9 +4176,21 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, gi
if (!(method->wrapper_type == MONO_WRAPPER_REMOTING_INVOKE ||
method->wrapper_type == MONO_WRAPPER_REMOTING_INVOKE_WITH_CHECK ||
method->wrapper_type == MONO_WRAPPER_XDOMAIN_INVOKE)) {
if (!mono_runtime_class_init_full (vtable, error))
if (!mono_runtime_class_init_full (vtable, error)) {
mono_destroy_compile (cfg);
return NULL;
}
}

if (!code) {
mono_destroy_compile (cfg);
return NULL;
}

if (code_length)
*code_length = cfg->code_len;

mono_destroy_compile (cfg);
return code;
}

Expand Down
2 changes: 1 addition & 1 deletion mono/mini/mini.h
Original file line number Diff line number Diff line change
Expand Up @@ -2003,7 +2003,7 @@ void mono_disassemble_code (MonoCompile *cfg, guint8 *code, int
void mono_add_patch_info (MonoCompile *cfg, int ip, MonoJumpInfoType type, gconstpointer target) MONO_LLVM_INTERNAL;
void mono_add_patch_info_rel (MonoCompile *cfg, int ip, MonoJumpInfoType type, gconstpointer target, int relocation) MONO_LLVM_INTERNAL;
void mono_remove_patch_info (MonoCompile *cfg, int ip);
gpointer mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, gint32 opt, MonoError *error);
gpointer mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, gint32 opt, gint64 *code_length, MonoError *error);
GList *mono_varlist_insert_sorted (MonoCompile *cfg, GList *list, MonoMethodVar *mv, int sort_type);
GList *mono_varlist_sort (MonoCompile *cfg, GList *list, int sort_type);
void mono_analyze_liveness (MonoCompile *cfg);
Expand Down

0 comments on commit 018f498

Please sign in to comment.