Merge pull request #2200 from xmcclure/image-audit-oops
[mono.git] / mono / mini / mini-mips.c
index cc32f05f72828cf9f1a6a06fcded6d33be8a6bfe..de484d15b22cddf2b211c5f5c3624e723c13fcab 100644 (file)
@@ -57,9 +57,9 @@ enum {
 };
 
 /* This mutex protects architecture specific caches */
-#define mono_mini_arch_lock() EnterCriticalSection (&mini_arch_mutex)
-#define mono_mini_arch_unlock() LeaveCriticalSection (&mini_arch_mutex)
-static CRITICAL_SECTION mini_arch_mutex;
+#define mono_mini_arch_lock() mono_mutex_lock (&mini_arch_mutex)
+#define mono_mini_arch_unlock() mono_mutex_unlock (&mini_arch_mutex)
+static mono_mutex_t mini_arch_mutex;
 
 int mono_exc_esp_offset = 0;
 static int tls_mode = TLS_MODE_DETECT;
@@ -497,7 +497,7 @@ emit_memcpy (guint8 *code, int size, int dreg, int doffset, int sreg, int soffse
  * Returns the size of the activation frame.
  */
 int
-mono_arch_get_argument_info (MonoGenericSharingContext *gsctx, MonoMethodSignature *csig, int param_count, MonoJitArgumentInfo *arg_info)
+mono_arch_get_argument_info (MonoMethodSignature *csig, int param_count, MonoJitArgumentInfo *arg_info)
 {
        int k, frame_size = 0;
        guint32 size, align, pad;
@@ -518,7 +518,7 @@ mono_arch_get_argument_info (MonoGenericSharingContext *gsctx, MonoMethodSignatu
        arg_info [0].size = frame_size;
 
        for (k = 0; k < param_count; k++) {
-               size = mini_type_stack_size_full (NULL, csig->params [k], &align, csig->pinvoke);
+               size = mini_type_stack_size_full (csig->params [k], &align, csig->pinvoke);
 
                /* ignore alignment for now */
                align = 1;
@@ -544,7 +544,7 @@ mono_arch_get_argument_info (MonoGenericSharingContext *gsctx, MonoMethodSignatu
 #define MAX_ARCH_DELEGATE_PARAMS (4 - 1)
 
 static gpointer
-get_delegate_invoke_impl (gboolean has_target, gboolean param_count, guint32 *code_size)
+get_delegate_invoke_impl (MonoTrampInfo **info, gboolean has_target, gboolean param_count)
 {
        guint8 *code, *start;
 
@@ -579,8 +579,13 @@ get_delegate_invoke_impl (gboolean has_target, gboolean param_count, guint32 *co
                mono_arch_flush_icache (start, size);
        }
 
-       if (code_size)
-               *code_size = code - start;
+       if (has_target) {
+               *info = mono_tramp_info_create ("delegate_invoke_impl_has_target", start, code - start, NULL, NULL);
+       } else {
+               char *name = g_strdup_printf ("delegate_invoke_impl_target_%d", param_count);
+               *info = mono_tramp_info_create (name, start, code - start, NULL, NULL);
+               g_free (name);
+       }
 
        return start;
 }
@@ -595,19 +600,15 @@ GSList*
 mono_arch_get_delegate_invoke_impls (void)
 {
        GSList *res = NULL;
-       guint8 *code;
-       guint32 code_len;
+       MonoTrampInfo *info;
        int i;
-       char *tramp_name;
 
-       code = get_delegate_invoke_impl (TRUE, 0, &code_len);
-       res = g_slist_prepend (res, mono_tramp_info_create ("delegate_invoke_impl_has_target", code, code_len, NULL, NULL));
+       get_delegate_invoke_impl (&info, TRUE, 0);
+       res = g_slist_prepend (res, info);
 
        for (i = 0; i <= MAX_ARCH_DELEGATE_PARAMS; ++i) {
-               code = get_delegate_invoke_impl (FALSE, i, &code_len);
-               tramp_name = g_strdup_printf ("delegate_invoke_impl_target_%d", i);
-               res = g_slist_prepend (res, mono_tramp_info_create (tramp_name, code, code_len, NULL, NULL));
-               g_free (tramp_name);
+               get_delegate_invoke_impl (&info, FALSE, i);
+               res = g_slist_prepend (res, info);
        }
 
        return res;
@@ -630,10 +631,13 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
                        return cached;
                }
 
-               if (mono_aot_only)
+               if (mono_aot_only) {
                        start = mono_aot_get_trampoline ("delegate_invoke_impl_has_target");
-               else
-                       start = get_delegate_invoke_impl (TRUE, 0, NULL);
+               } else {
+                       MonoTrampInfo *info;
+                       start = get_delegate_invoke_impl (&info, TRUE, 0);
+                       mono_tramp_info_register (info, NULL);
+               }
                cached = start;
                mono_mini_arch_unlock ();
                return cached;
@@ -659,7 +663,9 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
                        start = mono_aot_get_trampoline (name);
                        g_free (name);
                } else {
-                       start = get_delegate_invoke_impl (FALSE, sig->param_count, NULL);
+                       MonoTrampInfo *info;
+                       start = get_delegate_invoke_impl (&info, FALSE, sig->param_count);
+                       mono_tramp_info_register (info, NULL);
                }
                cache [sig->param_count] = start;
                mono_mini_arch_unlock ();
@@ -669,6 +675,12 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
        return NULL;
 }
 
+gpointer
+mono_arch_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod *method, int offset, gboolean load_imt_reg)
+{
+       return NULL;
+}
+
 gpointer
 mono_arch_get_this_arg_from_call (mgreg_t *regs, guint8 *code)
 {
@@ -701,7 +713,7 @@ mono_arch_cpu_init (void)
 void
 mono_arch_init (void)
 {
-       InitializeCriticalSection (&mini_arch_mutex);
+       mono_mutex_init_recursive (&mini_arch_mutex);
 
        ss_trigger_page = mono_valloc (NULL, mono_pagesize (), MONO_MMAP_READ|MONO_MMAP_32BIT);
        bp_trigger_page = mono_valloc (NULL, mono_pagesize (), MONO_MMAP_READ|MONO_MMAP_32BIT);
@@ -714,7 +726,7 @@ mono_arch_init (void)
 void
 mono_arch_cleanup (void)
 {
-       DeleteCriticalSection (&mini_arch_mutex);
+       mono_mutex_destroy (&mini_arch_mutex);
 }
 
 /*
@@ -1048,7 +1060,7 @@ add_float64_arg (CallInfo *info, ArgInfo *ainfo) {
 #endif
 
 static CallInfo*
-get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSignature *sig)
+get_call_info (MonoMemPool *mp, MonoMethodSignature *sig)
 {
        guint i;
        int n = sig->hasthis + sig->param_count;
@@ -1090,7 +1102,7 @@ get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSign
         * are sometimes made using calli without sig->hasthis set, like in the delegate
         * invoke wrappers.
         */
-       if (cinfo->vtype_retaddr && !is_pinvoke && (sig->hasthis || (sig->param_count > 0 && MONO_TYPE_IS_REFERENCE (mini_type_get_underlying_type (gsctx, sig->params [0]))))) {
+       if (cinfo->vtype_retaddr && !is_pinvoke && (sig->hasthis || (sig->param_count > 0 && MONO_TYPE_IS_REFERENCE (mini_get_underlying_type (sig->params [0]))))) {
                if (sig->hasthis) {
                        add_int32_arg (cinfo, cinfo->args + n);
                        n ++;
@@ -1125,7 +1137,7 @@ get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSign
                        add_int32_arg (cinfo, &cinfo->sig_cookie);
                }
                DEBUG(printf("param %d: ", i));
-               simpletype = mini_type_get_underlying_type (gsctx, sig->params [i]);
+               simpletype = mini_get_underlying_type (sig->params [i]);
                switch (simpletype->type) {
                case MONO_TYPE_BOOLEAN:
                case MONO_TYPE_I1:
@@ -1272,7 +1284,7 @@ get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSign
        }
 
        {
-               simpletype = mini_type_get_underlying_type (gsctx, sig->ret);
+               simpletype = mini_get_underlying_type (sig->ret);
                switch (simpletype->type) {
                case MONO_TYPE_BOOLEAN:
                case MONO_TYPE_I1:
@@ -1356,7 +1368,7 @@ mono_arch_compute_omit_fp (MonoCompile *cfg)
        sig = mono_method_signature (cfg->method);
 
        if (!cfg->arch.cinfo)
-               cfg->arch.cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig);
+               cfg->arch.cinfo = get_call_info (cfg->mempool, sig);
        cinfo = cfg->arch.cinfo;
 
        /*
@@ -1421,7 +1433,7 @@ mono_arch_allocate_vars (MonoCompile *cfg)
        sig = mono_method_signature (cfg->method);
 
        if (!cfg->arch.cinfo)
-               cfg->arch.cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig);
+               cfg->arch.cinfo = get_call_info (cfg->mempool, sig);
        cinfo = cfg->arch.cinfo;
 
        mono_arch_compute_omit_fp (cfg);
@@ -1464,7 +1476,7 @@ mono_arch_allocate_vars (MonoCompile *cfg)
        curinst = 0;
        if (!MONO_TYPE_ISSTRUCT (sig->ret)) {
                /* FIXME: handle long and FP values */
-               switch (mini_type_get_underlying_type (cfg->generic_sharing_context, sig->ret)->type) {
+               switch (mini_get_underlying_type (sig->ret)->type) {
                case MONO_TYPE_VOID:
                        break;
                case MONO_TYPE_R4:
@@ -1699,7 +1711,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
        sig = call->signature;
        n = sig->param_count + sig->hasthis;
        
-       cinfo = get_call_info (NULL, cfg->mempool, sig);
+       cinfo = get_call_info (cfg->mempool, sig);
        if (cinfo->struct_ret)
                call->used_iregs |= 1 << cinfo->struct_ret;
 
@@ -1711,7 +1723,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
                        t = sig->params [i - sig->hasthis];
                else
                        t = &mono_defaults.int_class->byval_arg;
-               t = mini_type_get_underlying_type (cfg->generic_sharing_context, t);
+               t = mini_get_underlying_type (t);
 
                if ((sig->call_convention == MONO_CALL_VARARG) && (i == sig->sentinelpos)) {
                        /* Emit the signature cookie just before the implicit arguments */
@@ -1929,7 +1941,7 @@ mono_arch_emit_outarg_vt (MonoCompile *cfg, MonoInst *ins, MonoInst *src)
                        size = mono_type_native_stack_size (&src->klass->byval_arg, NULL);
                        vtcopy->backend.is_pinvoke = 1;
                } else {
-                       size = mini_type_stack_size (cfg->generic_sharing_context, &src->klass->byval_arg, NULL);
+                       size = mini_type_stack_size (&src->klass->byval_arg, NULL);
                }
                if (size > 0)
                        g_assert (ovf_size > 0);
@@ -1947,8 +1959,7 @@ mono_arch_emit_outarg_vt (MonoCompile *cfg, MonoInst *ins, MonoInst *src)
 void
 mono_arch_emit_setret (MonoCompile *cfg, MonoMethod *method, MonoInst *val)
 {
-       MonoType *ret = mini_type_get_underlying_type (cfg->generic_sharing_context,
-                       mono_method_signature (method)->ret);
+       MonoType *ret = mini_get_underlying_type (mono_method_signature (method)->ret);
 
        if (!ret->byref) {
 #if (SIZEOF_REGISTER == 4)
@@ -3204,7 +3215,7 @@ emit_load_volatile_arguments(MonoCompile *cfg, guint8 *code)
        sig = mono_method_signature (method);
 
        if (!cfg->arch.cinfo)
-               cfg->arch.cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig);
+               cfg->arch.cinfo = get_call_info (cfg->mempool, sig);
        cinfo = cfg->arch.cinfo;
 
        if (cinfo->struct_ret) {
@@ -3299,8 +3310,8 @@ emit_reserve_param_area (MonoCompile *cfg, guint8 *code)
        if (ppc_is_imm16 (-size)) {
                ppc_stwu (code, ppc_r0, -size, ppc_sp);
        } else {
-               ppc_load (code, ppc_r11, -size);
-               ppc_stwux (code, ppc_r0, ppc_sp, ppc_r11);
+               ppc_load (code, ppc_r12, -size);
+               ppc_stwux (code, ppc_r0, ppc_sp, ppc_r12);
        }
 #endif
        return code;
@@ -3321,8 +3332,8 @@ emit_unreserve_param_area (MonoCompile *cfg, guint8 *code)
        if (ppc_is_imm16 (size)) {
                ppc_stwu (code, ppc_r0, size, ppc_sp);
        } else {
-               ppc_load (code, ppc_r11, size);
-               ppc_stwux (code, ppc_r0, ppc_sp, ppc_r11);
+               ppc_load (code, ppc_r12, size);
+               ppc_stwux (code, ppc_r0, ppc_sp, ppc_r12);
        }
 #endif
        return code;
@@ -3388,6 +3399,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                case OP_NOT_REACHED:
                case OP_NOT_NULL:
                        break;
+               case OP_IL_SEQ_POINT:
+                       mono_add_seq_point (cfg, bb, ins, code - cfg->native_code);
+                       break;
                case OP_SEQ_POINT: {
                        if (ins->flags & MONO_INST_SINGLE_STEP_LOC) {
                                guint32 addr = (guint32)ss_trigger_page;
@@ -3425,9 +3439,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        mips_mfhi (code, ins->dreg+1);
                        break;
                case OP_MEMORY_BARRIER:
-#if 0
-                       ppc_sync (code);
-#endif
+                       mips_sync (code, 0);
                        break;
                case OP_STOREI1_MEMBASE_IMM:
                        mips_load_const (code, mips_temp, ins->inst_imm);
@@ -3713,8 +3725,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                case OP_DIV_IMM:
                        g_assert_not_reached ();
 #if 0
-                       ppc_load (code, ppc_r11, ins->inst_imm);
-                       ppc_divwod (code, ins->dreg, ins->sreg1, ppc_r11);
+                       ppc_load (code, ppc_r12, ins->inst_imm);
+                       ppc_divwod (code, ins->dreg, ins->sreg1, ppc_r12);
                        ppc_mfspr (code, ppc_r0, ppc_xer);
                        ppc_andisd (code, ppc_r0, ppc_r0, (1<<14));
                        /* FIXME: use OverflowException for 0x80000000/-1 */
@@ -3906,6 +3918,14 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                                mips_fmovd (code, ins->dreg, ins->sreg1);
                        }
                        break;
+               case OP_MOVE_F_TO_I4:
+                       mips_cvtsd (code, mips_ftemp, ins->sreg1);
+                       mips_mfc1 (code, ins->dreg, mips_ftemp);
+                       break;
+               case OP_MOVE_I4_TO_F:
+                       mips_mtc1 (code, ins->dreg, ins->sreg1);
+                       mips_cvtds (code, ins->dreg, ins->dreg);
+                       break;
                case OP_MIPS_CVTSD:
                        /* Convert from double to float and leave it there */
                        mips_cvtsd (code, ins->dreg, ins->sreg1);
@@ -4620,6 +4640,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        mono_add_patch_info (cfg, offset, (MonoJumpInfoType)ins->inst_c1, ins->inst_p0);
                        mips_load (code, ins->dreg, 0x0f0f0f0f);
                        break;
+               case OP_GC_SAFE_POINT:
+                       break;
 
 
                default:
@@ -4648,7 +4670,7 @@ mono_arch_register_lowlevel_calls (void)
 }
 
 void
-mono_arch_patch_code (MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *ji, MonoCodeManager *dyn_code_mp, gboolean run_cctors)
+mono_arch_patch_code (MonoCompile *cfg, MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *ji, gboolean run_cctors)
 {
        MonoJumpInfo *patch_info;
 
@@ -5086,7 +5108,7 @@ mono_arch_emit_prolog (MonoCompile *cfg)
        pos = 0;
 
        if (!cfg->arch.cinfo)
-               cfg->arch.cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig);
+               cfg->arch.cinfo = get_call_info (cfg->mempool, sig);
        cinfo = cfg->arch.cinfo;
 
        if (MONO_TYPE_ISSTRUCT (sig->ret)) {
@@ -5325,7 +5347,7 @@ mono_arch_instrument_epilog_full (MonoCompile *cfg, void *func, void *p, gboolea
        int save_mode = SAVE_NONE;
        int offset;
        MonoMethod *method = cfg->method;
-       int rtype = mini_type_get_underlying_type (cfg->generic_sharing_context, mono_method_signature (method)->ret)->type;
+       int rtype = mini_get_underlying_type (mono_method_signature (method)->ret)->type;
        int save_offset = MIPS_STACK_PARAM_OFFSET;
 
        g_assert ((save_offset & (MIPS_STACK_ALIGNMENT-1)) == 0);
@@ -5799,13 +5821,13 @@ mono_arch_emit_this_vret_args (MonoCompile *cfg, MonoCallInst *inst, int this_re
 
        /* add the this argument */
        if (this_reg != -1) {
-               MonoInst *this;
-               MONO_INST_NEW (cfg, this, OP_MOVE);
-               this->type = this_type;
-               this->sreg1 = this_reg;
-               this->dreg = mono_alloc_ireg (cfg);
-               mono_bblock_add_inst (cfg->cbb, this);
-               mono_call_inst_add_outarg_reg (cfg, inst, this->dreg, this_dreg, FALSE);
+               MonoInst *this_ins;
+               MONO_INST_NEW (cfg, this_ins, OP_MOVE);
+               this_ins->type = this_type;
+               this_ins->sreg1 = this_reg;
+               this_ins->dreg = mono_alloc_ireg (cfg);
+               mono_bblock_add_inst (cfg->cbb, this_ins);
+               mono_call_inst_add_outarg_reg (cfg, inst, this_ins->dreg, this_dreg, FALSE);
        }
 
        if (vt_reg != -1) {
@@ -5990,6 +6012,9 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
                mono_stats.imt_thunks_size += code - start;
        g_assert (code - start <= size);
        mono_arch_flush_icache (start, size);
+
+       mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, NULL), domain);
+
        return start;
 }