[runtime] Add a few mono mono_class_is_... accessors. (#3891)
[mono.git] / mono / mini / exceptions-amd64.c
index 3f039f74b3e71ad570f7b0cbe5df185b6329566f..dbef0887519b5e12e85ba3320e952eef4a086c15 100644 (file)
@@ -6,6 +6,7 @@
  *
  * (C) 2001 Ximian, Inc.
  * Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
 #include <config.h>
@@ -151,6 +152,7 @@ void win32_seh_set_handler(int type, MonoW32ExceptionHandler handler)
 
 #endif /* TARGET_WIN32 */
 
+#ifndef DISABLE_JIT
 /*
  * mono_arch_get_restore_context:
  *
@@ -174,10 +176,6 @@ mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot)
        /* Restore all registers except %rip and %r11 */
        gregs_offset = MONO_STRUCT_OFFSET (MonoContext, gregs);
        for (i = 0; i < AMD64_NREG; ++i) {
-#if defined(__native_client_codegen__)
-               if (i == AMD64_R15)
-                       continue;
-#endif
                if (i != AMD64_RIP && i != AMD64_RSP && i != AMD64_R8 && i != AMD64_R9 && i != AMD64_R10 && i != AMD64_R11)
                        amd64_mov_reg_membase (code, i, AMD64_R11, gregs_offset + (i * 8), 8);
        }
@@ -197,8 +195,6 @@ mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot)
        /* jump to the saved IP */
        amd64_jump_reg (code, AMD64_R11);
 
-       nacl_global_codeman_validate (&start, 256, &code);
-
        mono_arch_flush_icache (start, code - start);
        mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL);
 
@@ -224,7 +220,7 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot)
        guint32 pos;
        MonoJumpInfo *ji = NULL;
        GSList *unwind_ops = NULL;
-       const guint kMaxCodeSize = NACL_SIZE (128, 256);
+       const guint kMaxCodeSize = 128;
 
        start = code = (guint8 *)mono_global_codeman_reserve (kMaxCodeSize);
 
@@ -257,12 +253,8 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot)
        amd64_mov_reg_membase (code, AMD64_RBP, AMD64_ARG_REG1, gregs_offset + (AMD64_RBP * 8), 8);
        /* load callee saved regs */
        for (i = 0; i < AMD64_NREG; ++i) {
-#if defined(__native_client_codegen__)
-               if (i == AMD64_R15)
-                       continue;
-#endif
                if (AMD64_IS_CALLEE_SAVED_REG (i) && i != AMD64_RBP)
-                       amd64_mov_reg_membase (code, AMD64_RBX, AMD64_ARG_REG1, gregs_offset + (i * 8), 8);
+                       amd64_mov_reg_membase (code, i, AMD64_ARG_REG1, gregs_offset + (i * 8), 8);
        }
        /* load exc register */
        amd64_mov_reg_membase (code, AMD64_RAX, AMD64_ARG_REG1,  gregs_offset + (AMD64_RAX * 8), 8);
@@ -286,8 +278,6 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot)
 
        g_assert ((code - start) < kMaxCodeSize);
 
-       nacl_global_codeman_validate(&start, kMaxCodeSize, &code);
-
        mono_arch_flush_icache (start, code - start);
        mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL);
 
@@ -296,6 +286,7 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot)
 
        return start;
 }
+#endif /* !DISABLE_JIT */
 
 /* 
  * The first few arguments are dummy, to force the other arguments to be passed on
@@ -306,18 +297,20 @@ mono_amd64_throw_exception (guint64 dummy1, guint64 dummy2, guint64 dummy3, guin
                                                        guint64 dummy5, guint64 dummy6,
                                                        MonoContext *mctx, MonoObject *exc, gboolean rethrow)
 {
+       MonoError error;
        MonoContext ctx;
 
        /* mctx is on the caller's stack */
        memcpy (&ctx, mctx, sizeof (MonoContext));
 
-       if (mono_object_isinst (exc, mono_defaults.exception_class)) {
+       if (mono_object_isinst_checked (exc, mono_defaults.exception_class, &error)) {
                MonoException *mono_ex = (MonoException*)exc;
                if (!rethrow) {
                        mono_ex->stack_trace = NULL;
                        mono_ex->trace_ips = NULL;
                }
        }
+       mono_error_assert_ok (&error);
 
        /* adjust eip so that it point into the call instruction */
        ctx.gregs [AMD64_RIP] --;
@@ -359,6 +352,7 @@ mono_amd64_resume_unwind (guint64 dummy1, guint64 dummy2, guint64 dummy3, guint6
        mono_resume_unwind (&ctx);
 }
 
+#ifndef DISABLE_JIT
 /*
  * get_throw_trampoline:
  *
@@ -373,7 +367,7 @@ get_throw_trampoline (MonoTrampInfo **info, gboolean rethrow, gboolean corlib, g
        MonoJumpInfo *ji = NULL;
        GSList *unwind_ops = NULL;
        int i, stack_size, arg_offsets [16], ctx_offset, regs_offset, dummy_stack_space;
-       const guint kMaxCodeSize = NACL_SIZE (256, 512);
+       const guint kMaxCodeSize = 256;
 
 #ifdef TARGET_WIN32
        dummy_stack_space = 6 * sizeof(mgreg_t);        /* Windows expects stack space allocated for all 6 dummy args. */
@@ -415,10 +409,7 @@ get_throw_trampoline (MonoTrampInfo **info, gboolean rethrow, gboolean corlib, g
        amd64_lea_membase (code, AMD64_RAX, AMD64_RSP, stack_size + sizeof(mgreg_t));
        amd64_mov_membase_reg (code, AMD64_RSP, regs_offset + (AMD64_RSP * sizeof(mgreg_t)), X86_EAX, sizeof(mgreg_t));
        /* Save IP */
-       if (llvm_abs)
-               amd64_alu_reg_reg (code, X86_XOR, AMD64_RAX, AMD64_RAX);
-       else
-               amd64_mov_reg_membase (code, AMD64_RAX, AMD64_RSP, stack_size, sizeof(mgreg_t));
+       amd64_mov_reg_membase (code, AMD64_RAX, AMD64_RSP, stack_size, sizeof(mgreg_t));
        amd64_mov_membase_reg (code, AMD64_RSP, regs_offset + (AMD64_RIP * sizeof(mgreg_t)), AMD64_RAX, sizeof(mgreg_t));
        /* Set arg1 == ctx */
        amd64_lea_membase (code, AMD64_RAX, AMD64_RSP, ctx_offset);
@@ -432,14 +423,14 @@ get_throw_trampoline (MonoTrampInfo **info, gboolean rethrow, gboolean corlib, g
        if (resume_unwind) {
                amd64_mov_membase_imm (code, AMD64_RSP, arg_offsets [2], 0, sizeof(mgreg_t));
        } else if (corlib) {
-               amd64_mov_membase_reg (code, AMD64_RSP, arg_offsets [2], AMD64_ARG_REG2, sizeof(mgreg_t));
                if (llvm_abs)
-                       /* 
-                        * The caller is LLVM code which passes the absolute address not a pc offset,
-                        * so compensate by passing 0 as 'rip' and passing the negated abs address as
-                        * the pc offset.
+                       /*
+                        * The caller doesn't pass in a pc/pc offset, instead we simply use the
+                        * caller ip. Negate the pc adjustment done in mono_amd64_throw_corlib_exception ().
                         */
-                       amd64_neg_membase (code, AMD64_RSP, arg_offsets [2]);
+                       amd64_mov_membase_imm (code, AMD64_RSP, arg_offsets [2], 1, sizeof(mgreg_t));
+               else
+                       amd64_mov_membase_reg (code, AMD64_RSP, arg_offsets [2], AMD64_ARG_REG2, sizeof(mgreg_t));
        } else {
                amd64_mov_membase_imm (code, AMD64_RSP, arg_offsets [2], rethrow, sizeof(mgreg_t));
        }
@@ -465,7 +456,6 @@ get_throw_trampoline (MonoTrampInfo **info, gboolean rethrow, gboolean corlib, g
 
        g_assert ((code - start) < kMaxCodeSize);
 
-       nacl_global_codeman_validate(&start, kMaxCodeSize, &code);
        mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL);
 
        if (info)
@@ -509,6 +499,7 @@ mono_arch_get_throw_corlib_exception (MonoTrampInfo **info, gboolean aot)
 {
        return get_throw_trampoline (info, FALSE, TRUE, FALSE, FALSE, "throw_corlib_exception", aot);
 }
+#endif /* !DISABLE_JIT */
 
 /*
  * mono_arch_unwind_frame:
@@ -846,6 +837,7 @@ mono_amd64_get_original_ip (void)
        return lmf->rip;
 }
 
+#ifndef DISABLE_JIT
 GSList*
 mono_amd64_get_exception_trampolines (gboolean aot)
 {
@@ -864,6 +856,7 @@ mono_amd64_get_exception_trampolines (gboolean aot)
 
        return tramps;
 }
+#endif /* !DISABLE_JIT */
 
 void
 mono_arch_exceptions_init (void)
@@ -891,7 +884,7 @@ mono_arch_exceptions_init (void)
        }
 }
 
-#ifdef TARGET_WIN32
+#if defined(TARGET_WIN32) && !defined(DISABLE_JIT)
 
 /*
  * The mono_arch_unwindinfo* methods are used to build and add
@@ -1131,16 +1124,16 @@ mono_arch_unwindinfo_install_unwind_info (gpointer* monoui, gpointer code, guint
        RtlInstallFunctionTableCallback (((DWORD64)code) | 0x3, (DWORD64)code, code_size, MONO_GET_RUNTIME_FUNCTION_CALLBACK, code, NULL);
 }
 
-#endif
+#endif /* defined(TARGET_WIN32) !defined(DISABLE_JIT) */
 
-#if MONO_SUPPORT_TASKLETS
+#if MONO_SUPPORT_TASKLETS && !defined(DISABLE_JIT)
 MonoContinuationRestore
 mono_tasklets_arch_restore (void)
 {
        static guint8* saved = NULL;
        guint8 *code, *start;
        int cont_reg = AMD64_R9; /* register usable on both call conventions */
-       const guint kMaxCodeSize = NACL_SIZE (64, 128);
+       const guint kMaxCodeSize = 64;
        
 
        if (saved)
@@ -1165,26 +1158,27 @@ mono_tasklets_arch_restore (void)
        amd64_movsl (code);
 
        /* now restore the registers from the LMF */
-       NOT_IMPLEMENTED;
        amd64_mov_reg_membase (code, AMD64_RCX, cont_reg, MONO_STRUCT_OFFSET (MonoContinuation, lmf), 8);
+       amd64_mov_reg_membase (code, AMD64_RBP, AMD64_RCX, MONO_STRUCT_OFFSET (MonoLMF, rbp), 8);
        amd64_mov_reg_membase (code, AMD64_RSP, AMD64_RCX, MONO_STRUCT_OFFSET (MonoLMF, rsp), 8);
 
-       /* restore the lmf chain */
-       /*x86_mov_reg_membase (code, X86_ECX, X86_ESP, 12, 4);
-       x86_mov_membase_reg (code, X86_ECX, 0, X86_EDX, 4);*/
+#ifdef WIN32
+       amd64_mov_reg_reg (code, AMD64_R14, AMD64_ARG_REG3, 8);
+#else
+       amd64_mov_reg_reg (code, AMD64_R12, AMD64_ARG_REG3, 8);
+#endif
 
        /* state is already in rax */
        amd64_jump_membase (code, cont_reg, MONO_STRUCT_OFFSET (MonoContinuation, return_ip));
        g_assert ((code - start) <= kMaxCodeSize);
 
-       nacl_global_codeman_validate(&start, kMaxCodeSize, &code);
        mono_arch_flush_icache (start, code - start);
        mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL);
 
        saved = start;
        return (MonoContinuationRestore)saved;
 }
-#endif
+#endif /* MONO_SUPPORT_TASKLETS && !defined(DISABLE_JIT) */
 
 /*
  * mono_arch_setup_resume_sighandler_ctx:
@@ -1202,3 +1196,56 @@ mono_arch_setup_resume_sighandler_ctx (MonoContext *ctx, gpointer func)
                MONO_CONTEXT_SET_SP (ctx, (guint64)MONO_CONTEXT_GET_SP (ctx) - 8);
        MONO_CONTEXT_SET_IP (ctx, func);
 }
+
+#ifdef DISABLE_JIT
+gpointer
+mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot)
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+
+gpointer
+mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot)
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+
+gpointer
+mono_arch_get_throw_exception (MonoTrampInfo **info, gboolean aot)
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+
+gpointer
+mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot)
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+
+gpointer
+mono_arch_get_throw_corlib_exception (MonoTrampInfo **info, gboolean aot)
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+
+GSList*
+mono_amd64_get_exception_trampolines (gboolean aot)
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+#endif /* DISABLE_JIT */
+
+#if !MONO_SUPPORT_TASKLETS || defined(DISABLE_JIT)
+MonoContinuationRestore
+mono_tasklets_arch_restore (void)
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+#endif /* !MONO_SUPPORT_TASKLETS || defined(DISABLE_JIT) */