Add code manager callbacks so JIT can track memory chunk ranges and register stack...
authorJonathan Chambers <joncham@gmail.com>
Sat, 7 Jan 2017 09:00:37 +0000 (04:00 -0500)
committerZoltan Varga <vargaz@gmail.com>
Sat, 7 Jan 2017 09:00:37 +0000 (04:00 -0500)
mono/mini/exceptions-amd64.c
mono/mini/mini-amd64.h
mono/mini/mini-runtime.c
mono/utils/mono-codeman.c
mono/utils/mono-codeman.h

index 2090acb778bb68cbc1df6fecd0926b17fa2fa370..38c333c466cadf36d6e9b77e9c59bc514decc018 100644 (file)
@@ -1090,6 +1090,8 @@ MONO_GET_RUNTIME_FUNCTION_CALLBACK ( DWORD64 ControlPc, IN PVOID Context )
        
        targetinfo = (PMonoUnwindInfo)ALIGN_TO (pos, 8);
 
+       targetinfo->runtimeFunction.BeginAddress = ((DWORD64)ji->code_start) - ((DWORD64)Context);
+       targetinfo->runtimeFunction.EndAddress = pos - ((DWORD64)Context);
        targetinfo->runtimeFunction.UnwindData = ((DWORD64)&targetinfo->unwindInfo) - ((DWORD64)Context);
 
        return &targetinfo->runtimeFunction;
@@ -1121,8 +1123,19 @@ mono_arch_unwindinfo_install_unwind_info (gpointer* monoui, gpointer code, guint
 
        g_free (unwindinfo);
        *monoui = 0;
+}
+
+void
+mono_arch_code_chunk_new (void *chunk, int size)
+{
+       BOOLEAN success = RtlInstallFunctionTableCallback (((DWORD64)chunk) | 0x3, (DWORD64)chunk, size, MONO_GET_RUNTIME_FUNCTION_CALLBACK, chunk, NULL);
+       g_assert (success);
+}
 
-       RtlInstallFunctionTableCallback (((DWORD64)code) | 0x3, (DWORD64)code, code_size, MONO_GET_RUNTIME_FUNCTION_CALLBACK, code, NULL);
+void mono_arch_code_chunk_destroy (void *chunk)
+{
+       BOOLEAN success = RtlDeleteFunctionTable ((PRUNTIME_FUNCTION)((DWORD64)chunk | 0x03));
+       g_assert (success);
 }
 
 #endif /* defined(TARGET_WIN32) !defined(DISABLE_JIT) */
index e34ec40036f1d676d4da83e3f029aeed21d91da4..0702600fa3700e3b2e652d6ebdb61f0bf5b4a008 100644 (file)
@@ -485,6 +485,10 @@ guint mono_arch_unwindinfo_get_size (gpointer monoui);
 void mono_arch_unwindinfo_install_unwind_info (gpointer* monoui, gpointer code, guint code_size);
 
 #define MONO_ARCH_HAVE_UNWIND_TABLE 1
+
+void mono_arch_code_chunk_new (void *chunk, int size);
+void mono_arch_code_chunk_destroy (void *chunk);
+#define MONO_ARCH_HAVE_CODE_CHUNK_TRACKING 1
 #endif
 
 CallInfo* mono_arch_get_call_info (MonoMemPool *mp, MonoMethodSignature *sig);
index 98cd4f6cbead2087abe27f5b5873a331775ab860..706a777bcc55bdac29c51e73782797bf0af5d4e4 100644 (file)
@@ -3409,6 +3409,22 @@ mini_free_jit_domain_info (MonoDomain *domain)
        domain->runtime_info = NULL;
 }
 
+#ifdef MONO_ARCH_HAVE_CODE_CHUNK_TRACKING
+
+static void
+code_manager_chunk_new (void *chunk, int size)
+{
+       mono_arch_code_chunk_new (chunk, size);
+}
+
+static void
+code_manager_chunk_destroy (void *chunk)
+{
+       mono_arch_code_chunk_destroy (chunk);
+}
+
+#endif
+
 #ifdef ENABLE_LLVM
 static gboolean
 llvm_init_inner (void)
@@ -3453,6 +3469,7 @@ mini_init (const char *filename, const char *runtime_version)
        MonoDomain *domain;
        MonoRuntimeCallbacks callbacks;
        MonoThreadInfoRuntimeCallbacks ticallbacks;
+       MonoCodeManagerCallbacks code_manager_callbacks;
 
        MONO_VES_INIT_BEGIN ();
 
@@ -3536,6 +3553,13 @@ mini_init (const char *filename, const char *runtime_version)
 
        mono_code_manager_init ();
 
+       memset (&code_manager_callbacks, 0, sizeof (code_manager_callbacks));
+#ifdef MONO_ARCH_HAVE_CODE_CHUNK_TRACKING
+       code_manager_callbacks.chunk_new = code_manager_chunk_new;
+       code_manager_callbacks.chunk_destroy = code_manager_chunk_destroy;
+#endif
+       mono_code_manager_install_callbacks (&code_manager_callbacks);
+
        mono_hwcap_init ();
 
        mono_arch_cpu_init ();
index f29a67ca096690a978db2922ef8717ce7afa1920..ba3ec4ea132a8e8acd7d9c4ab62f53ec0ac88c14 100644 (file)
@@ -28,6 +28,7 @@ static uintptr_t code_memory_used = 0;
 static size_t dynamic_code_alloc_count;
 static size_t dynamic_code_bytes_count;
 static size_t dynamic_code_frees_count;
+static MonoCodeManagerCallbacks code_manager_callbacks;
 
 /*
  * AMD64 processors maintain icache coherency only for pages which are 
@@ -174,6 +175,12 @@ mono_code_manager_cleanup (void)
        codechunk_cleanup ();
 }
 
+void
+mono_code_manager_install_callbacks (MonoCodeManagerCallbacks* callbacks)
+{
+       code_manager_callbacks = *callbacks;
+}
+
 /**
  * mono_code_manager_new:
  *
@@ -226,6 +233,8 @@ free_chunklist (CodeChunk *chunk)
        for (; chunk; ) {
                dead = chunk;
                mono_profiler_code_chunk_destroy ((gpointer) dead->data);
+               if (code_manager_callbacks.chunk_destroy)
+                       code_manager_callbacks.chunk_destroy ((gpointer)dead->data);
                chunk = chunk->next;
                if (dead->flags == CODE_FLAG_MMAP) {
                        codechunk_vfree (dead->data, dead->size);
@@ -413,6 +422,8 @@ new_codechunk (CodeChunk *last, int dynamic, int size)
        chunk->flags = flags;
        chunk->pos = bsize;
        chunk->bsize = bsize;
+       if (code_manager_callbacks.chunk_new)
+               code_manager_callbacks.chunk_new ((gpointer)chunk->data, chunk->size);
        mono_profiler_code_chunk_new((gpointer) chunk->data, chunk->size);
 
        code_memory_used += chunk_size;
index 8a1070a101dff637cd9324236fd69f633caf453b..166899caafff31a14afdf59fa75b88d2e3f2956d 100644 (file)
@@ -5,6 +5,11 @@
 
 typedef struct _MonoCodeManager MonoCodeManager;
 
+typedef struct {
+       void (*chunk_new) (void *chunk, int size);
+       void (*chunk_destroy) (void *chunk);
+} MonoCodeManagerCallbacks;
+
 MONO_API MonoCodeManager* mono_code_manager_new     (void);
 MONO_API MonoCodeManager* mono_code_manager_new_dynamic (void);
 MONO_API void             mono_code_manager_destroy (MonoCodeManager *cman);
@@ -18,6 +23,7 @@ MONO_API void             mono_code_manager_commit  (MonoCodeManager *cman, void
 MONO_API int              mono_code_manager_size    (MonoCodeManager *cman, int *used_size);
 MONO_API void             mono_code_manager_init (void);
 MONO_API void             mono_code_manager_cleanup (void);
+MONO_API void             mono_code_manager_install_callbacks (MonoCodeManagerCallbacks* callbacks);
 
 /* find the extra block allocated to resolve branches close to code */
 typedef int    (*MonoCodeManagerFunc)      (void *data, int csize, int size, void *user_data);