2009-05-10 Miguel de Icaza <miguel@novell.com>
[mono.git] / mono / mini / mini-arm.c
index ac3c5db0eb4e8eacd93e012421a941a067404fbd..fd5f7b5fe0d08bba86b71f90f5a7a6dab13f5034 100644 (file)
@@ -194,6 +194,13 @@ emit_move_return_value (MonoCompile *cfg, MonoInst *ins, guint8 *code)
 #ifdef ARM_FPU_FPA
                if (ins->dreg != ARM_FPA_F0)
                        ARM_MVFD (code, ins->dreg, ARM_FPA_F0);
+#elif defined(ARM_FPU_VFP)
+               if (((MonoCallInst*)ins)->signature->ret->type == MONO_TYPE_R4) {
+                       ARM_FMSR (code, ins->dreg, ARMREG_R0);
+                       ARM_CVTS (code, ins->dreg, ins->dreg);
+               } else {
+                       ARM_FMDRR (code, ARMREG_R0, ARMREG_R1, ins->dreg);
+               }
 #endif
                break;
        }
@@ -335,18 +342,72 @@ mono_arch_get_vcall_slot (guint8 *code_ptr, gpointer *regs, int *displacement)
        return NULL;
 }
 
-gpointer*
-mono_arch_get_vcall_slot_addr (guint8* code, gpointer *regs)
+#define MAX_ARCH_DELEGATE_PARAMS 3
+
+static gpointer
+get_delegate_invoke_impl (gboolean has_target, gboolean param_count, guint32 *code_size)
 {
-       gpointer vt;
-       int displacement;
-       vt = mono_arch_get_vcall_slot (code, regs, &displacement);
-       if (!vt)
-               return NULL;
-       return (gpointer*)((char*)vt + displacement);
+       guint8 *code, *start;
+
+       if (has_target) {
+               start = code = mono_global_codeman_reserve (12);
+
+               /* Replace the this argument with the target */
+               ARM_LDR_IMM (code, ARMREG_IP, ARMREG_R0, G_STRUCT_OFFSET (MonoDelegate, method_ptr));
+               ARM_LDR_IMM (code, ARMREG_R0, ARMREG_R0, G_STRUCT_OFFSET (MonoDelegate, target));
+               ARM_MOV_REG_REG (code, ARMREG_PC, ARMREG_IP);
+
+               g_assert ((code - start) <= 12);
+
+               mono_arch_flush_icache (start, 12);
+       } else {
+               int size, i;
+
+               size = 8 + param_count * 4;
+               start = code = mono_global_codeman_reserve (size);
+
+               ARM_LDR_IMM (code, ARMREG_IP, ARMREG_R0, G_STRUCT_OFFSET (MonoDelegate, method_ptr));
+               /* slide down the arguments */
+               for (i = 0; i < param_count; ++i) {
+                       ARM_MOV_REG_REG (code, (ARMREG_R0 + i), (ARMREG_R0 + i + 1));
+               }
+               ARM_MOV_REG_REG (code, ARMREG_PC, ARMREG_IP);
+
+               g_assert ((code - start) <= size);
+
+               mono_arch_flush_icache (start, size);
+       }
+
+       if (code_size)
+               *code_size = code - start;
+
+       return start;
 }
 
-#define MAX_ARCH_DELEGATE_PARAMS 3
+/*
+ * mono_arch_get_delegate_invoke_impls:
+ *
+ *   Return a list of MonoAotTrampInfo structures for the delegate invoke impl
+ * trampolines.
+ */
+GSList*
+mono_arch_get_delegate_invoke_impls (void)
+{
+       GSList *res = NULL;
+       guint8 *code;
+       guint32 code_len;
+       int i;
+
+       code = get_delegate_invoke_impl (TRUE, 0, &code_len);
+       res = g_slist_prepend (res, mono_aot_tramp_info_create (g_strdup ("delegate_invoke_impl_has_target"), code, code_len));
+
+       for (i = 0; i < MAX_ARCH_DELEGATE_PARAMS; ++i) {
+               code = get_delegate_invoke_impl (FALSE, i, &code_len);
+               res = g_slist_prepend (res, mono_aot_tramp_info_create (g_strdup_printf ("delegate_invoke_impl_target_%d", i), code, code_len));
+       }
+
+       return res;
+}
 
 gpointer
 mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_target)
@@ -364,23 +425,17 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
                        mono_mini_arch_unlock ();
                        return cached;
                }
-               
-               start = code = mono_global_codeman_reserve (12);
-
-               /* Replace the this argument with the target */
-               ARM_LDR_IMM (code, ARMREG_IP, ARMREG_R0, G_STRUCT_OFFSET (MonoDelegate, method_ptr));
-               ARM_LDR_IMM (code, ARMREG_R0, ARMREG_R0, G_STRUCT_OFFSET (MonoDelegate, target));
-               ARM_MOV_REG_REG (code, ARMREG_PC, ARMREG_IP);
-
-               g_assert ((code - start) <= 12);
 
-               mono_arch_flush_icache (start, 12);
+               if (mono_aot_only)
+                       start = mono_aot_get_named_code ("delegate_invoke_impl_has_target");
+               else
+                       start = get_delegate_invoke_impl (TRUE, 0, NULL);
                cached = start;
                mono_mini_arch_unlock ();
                return cached;
        } else {
                static guint8* cache [MAX_ARCH_DELEGATE_PARAMS + 1] = {NULL};
-               int size, i;
+               int i;
 
                if (sig->param_count > MAX_ARCH_DELEGATE_PARAMS)
                        return NULL;
@@ -395,19 +450,13 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
                        return code;
                }
 
-               size = 8 + sig->param_count * 4;
-               start = code = mono_global_codeman_reserve (size);
-
-               ARM_LDR_IMM (code, ARMREG_IP, ARMREG_R0, G_STRUCT_OFFSET (MonoDelegate, method_ptr));
-               /* slide down the arguments */
-               for (i = 0; i < sig->param_count; ++i) {
-                       ARM_MOV_REG_REG (code, (ARMREG_R0 + i), (ARMREG_R0 + i + 1));
+               if (mono_aot_only) {
+                       char *name = g_strdup_printf ("delegate_invoke_impl_target_%d", sig->param_count);
+                       start = mono_aot_get_named_code (name);
+                       g_free (name);
+               } else {
+                       start = get_delegate_invoke_impl (FALSE, sig->param_count, NULL);
                }
-               ARM_MOV_REG_REG (code, ARMREG_PC, ARMREG_IP);
-
-               g_assert ((code - start) <= size);
-
-               mono_arch_flush_icache (start, size);
                cache [sig->param_count] = start;
                mono_mini_arch_unlock ();
                return start;
@@ -1321,6 +1370,16 @@ mono_arch_emit_setret (MonoCompile *cfg, MonoMethod *method, MonoInst *val)
                        MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, cfg->ret->dreg, val->dreg);
                        return;
                }                       
+#elif defined(ARM_FPU_VFP)
+               if (ret->type == MONO_TYPE_R8 || ret->type == MONO_TYPE_R4) {
+                       MonoInst *ins;
+
+                       MONO_INST_NEW (cfg, ins, OP_SETFRET);
+                       ins->dreg = cfg->ret->dreg;
+                       ins->sreg1 = val->dreg;
+                       MONO_ADD_INS (cfg->cbb, ins);
+                       return;
+               }
 #else
                if (ret->type == MONO_TYPE_R4 || ret->type == MONO_TYPE_R8) {
                        MONO_EMIT_NEW_UNALU (cfg, OP_FMOVE, cfg->ret->dreg, val->dreg);
@@ -1934,6 +1993,20 @@ loop_start:
        bb->max_vreg = cfg->next_vreg;
 }
 
+void
+mono_arch_decompose_long_opts (MonoCompile *cfg, MonoInst *long_ins)
+{
+       MonoInst *ins;
+       int vreg;
+
+       if (long_ins->opcode == OP_LNEG) {
+               ins = long_ins;
+               MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ARM_RSBS_IMM, ins->dreg + 1, ins->sreg1 + 1, 0);
+               MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ARM_RSC_IMM, ins->dreg + 2, ins->sreg1 + 2, 0);
+               NULLIFY_INS (ins);
+       }
+}
+
 static guchar*
 emit_float_to_int (MonoCompile *cfg, guchar *code, int dreg, int sreg, int size, gboolean is_signed)
 {
@@ -2045,12 +2118,12 @@ handle_thunk (int absolute, guchar *code, const guchar *target) {
        pdata.found = 0;
 
        mono_domain_lock (domain);
-       mono_code_manager_foreach (domain->code_mp, search_thunk_slot, &pdata);
+       mono_domain_code_foreach (domain, search_thunk_slot, &pdata);
 
        if (!pdata.found) {
                /* this uses the first available slot */
                pdata.found = 2;
-               mono_code_manager_foreach (domain->code_mp, search_thunk_slot, &pdata);
+               mono_domain_code_foreach (domain, search_thunk_slot, &pdata);
        }
        mono_domain_unlock (domain);
 
@@ -2853,7 +2926,15 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        code = emit_big_add (code, ARMREG_SP, cfg->frame_reg, cfg->stack_usage);
                        ARM_POP_NWB (code, cfg->used_int_regs | ((1 << ARMREG_SP)) | ((1 << ARMREG_LR)));
                        mono_add_patch_info (cfg, (guint8*) code - cfg->native_code, MONO_PATCH_INFO_METHOD_JUMP, ins->inst_p0);
-                       ARM_B (code, 0);
+                       if (cfg->compile_aot) {
+                               ARM_LDR_IMM (code, ARMREG_IP, ARMREG_PC, 0);
+                               ARM_B (code, 0);
+                               *(gpointer*)code = NULL;
+                               code += 4;
+                               ARM_LDR_REG_REG (code, ARMREG_PC, ARMREG_PC, ARMREG_IP);
+                       } else {
+                               ARM_B (code, 0);
+                       }
                        break;
                case OP_CHECK_THIS:
                        /* ensure ins->sreg1 is not NULL */
@@ -3170,6 +3251,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        /* This is generated by the local regalloc pass which runs after the lowering pass */
                        if (!arm_is_fpimm8 (ins->inst_offset)) {
                                code = mono_arm_emit_load_imm (code, ARMREG_LR, ins->inst_offset);
+                               ARM_ADD_REG_REG (code, ARMREG_LR, ARMREG_LR, ins->inst_destbasereg);
                                ARM_STFD (code, ins->sreg1, ARMREG_LR, 0);
                        } else {
                                ARM_STFD (code, ins->sreg1, ins->inst_destbasereg, ins->inst_offset);
@@ -3179,6 +3261,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        /* This is generated by the local regalloc pass which runs after the lowering pass */
                        if (!arm_is_fpimm8 (ins->inst_offset)) {
                                code = mono_arm_emit_load_imm (code, ARMREG_LR, ins->inst_offset);
+                               ARM_ADD_REG_REG (code, ARMREG_LR, ARMREG_LR, ins->inst_basereg);
                                ARM_LDFD (code, ins->dreg, ARMREG_LR, 0);
                        } else {
                                ARM_LDFD (code, ins->dreg, ins->inst_basereg, ins->inst_offset);
@@ -3224,7 +3307,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                case OP_ICONV_TO_R8:
                        ARM_FLTD (code, ins->dreg, ins->sreg1);
                        break;
+
 #elif defined(ARM_FPU_VFP)
+
                case OP_R8CONST:
                        if (cfg->compile_aot) {
                                ARM_FLDD (code, ins->dreg, ARMREG_PC, 0);
@@ -3255,34 +3340,60 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        }
                        break;
                case OP_STORER8_MEMBASE_REG:
-                       g_assert (arm_is_fpimm8 (ins->inst_offset));
-                       ARM_FSTD (code, ins->sreg1, ins->inst_destbasereg, ins->inst_offset);
+                       /* This is generated by the local regalloc pass which runs after the lowering pass */
+                       if (!arm_is_fpimm8 (ins->inst_offset)) {
+                               code = mono_arm_emit_load_imm (code, ARMREG_LR, ins->inst_offset);
+                               ARM_ADD_REG_REG (code, ARMREG_LR, ARMREG_LR, ins->inst_destbasereg);
+                               ARM_FSTD (code, ins->sreg1, ARMREG_LR, 0);
+                       } else {
+                               ARM_FSTD (code, ins->sreg1, ins->inst_destbasereg, ins->inst_offset);
+                       }
                        break;
                case OP_LOADR8_MEMBASE:
-                       g_assert (arm_is_fpimm8 (ins->inst_offset));
-                       ARM_FLDD (code, ins->dreg, ins->inst_basereg, ins->inst_offset);
+                       /* This is generated by the local regalloc pass which runs after the lowering pass */
+                       if (!arm_is_fpimm8 (ins->inst_offset)) {
+                               code = mono_arm_emit_load_imm (code, ARMREG_LR, ins->inst_offset);
+                               ARM_ADD_REG_REG (code, ARMREG_LR, ARMREG_LR, ins->inst_basereg);
+                               ARM_FLDD (code, ins->dreg, ARMREG_LR, 0);
+                       } else {
+                               ARM_FLDD (code, ins->dreg, ins->inst_basereg, ins->inst_offset);
+                       }
                        break;
                case OP_STORER4_MEMBASE_REG:
                        g_assert (arm_is_fpimm8 (ins->inst_offset));
-                       ARM_FSTS (code, ins->sreg1, ins->inst_destbasereg, ins->inst_offset);
+                       ARM_CVTD (code, ARM_VFP_F0, ins->sreg1);
+                       ARM_FSTS (code, ARM_VFP_F0, ins->inst_destbasereg, ins->inst_offset);
                        break;
                case OP_LOADR4_MEMBASE:
                        g_assert (arm_is_fpimm8 (ins->inst_offset));
-                       ARM_FLDS (code, ins->dreg, ins->inst_basereg, ins->inst_offset);
+                       ARM_FLDS (code, ARM_VFP_F0, ins->inst_basereg, ins->inst_offset);
+                       ARM_CVTS (code, ins->dreg, ARM_VFP_F0);
                        break;
                case OP_ICONV_TO_R_UN: {
                        g_assert_not_reached ();
                        break;
                }
                case OP_ICONV_TO_R4:
-                       g_assert_not_reached ();
-                       //ARM_FLTS (code, ins->dreg, ins->sreg1);
+                       ARM_FMSR (code, ARM_VFP_F0, ins->sreg1);
+                       ARM_FSITOS (code, ARM_VFP_F0, ARM_VFP_F0);
+                       ARM_CVTS (code, ins->dreg, ARM_VFP_F0);
                        break;
                case OP_ICONV_TO_R8:
-                       g_assert_not_reached ();
-                       //ARM_FLTD (code, ins->dreg, ins->sreg1);
+                       ARM_FMSR (code, ARM_VFP_F0, ins->sreg1);
+                       ARM_FSITOD (code, ins->dreg, ARM_VFP_F0);
                        break;
+
+               case OP_SETFRET:
+                       if (mono_method_signature (cfg->method)->ret->type == MONO_TYPE_R4) {
+                               ARM_CVTD (code, ARM_VFP_F0, ins->sreg1);
+                               ARM_FMRS (code, ARMREG_R0, ARM_VFP_F0);
+                       } else {
+                               ARM_FMRRD (code, ARMREG_R0, ARMREG_R1, ins->sreg1);
+                       }
+                       break;
+
 #endif
+
                case OP_FCONV_TO_I1:
                        code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 1, TRUE);
                        break;
@@ -3387,6 +3498,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        ARM_FCMP (code, ARM_FPA_CMF, ins->sreg1, ins->sreg2);
 #elif defined(ARM_FPU_VFP)
                        ARM_CMPD (code, ins->sreg1, ins->sreg2);
+                       ARM_FMSTAT (code);
 #endif
                        break;
                case OP_FCEQ:
@@ -3394,6 +3506,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        ARM_FCMP (code, ARM_FPA_CMF, ins->sreg1, ins->sreg2);
 #elif defined(ARM_FPU_VFP)
                        ARM_CMPD (code, ins->sreg1, ins->sreg2);
+                       ARM_FMSTAT (code);
 #endif
                        ARM_MOV_REG_IMM8_COND (code, ins->dreg, 0, ARMCOND_NE);
                        ARM_MOV_REG_IMM8_COND (code, ins->dreg, 1, ARMCOND_EQ);
@@ -3403,6 +3516,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        ARM_FCMP (code, ARM_FPA_CMF, ins->sreg1, ins->sreg2);
 #elif defined(ARM_FPU_VFP)
                        ARM_CMPD (code, ins->sreg1, ins->sreg2);
+                       ARM_FMSTAT (code);
 #endif
                        ARM_MOV_REG_IMM8 (code, ins->dreg, 0);
                        ARM_MOV_REG_IMM8_COND (code, ins->dreg, 1, ARMCOND_MI);
@@ -3412,6 +3526,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        ARM_FCMP (code, ARM_FPA_CMF, ins->sreg1, ins->sreg2);
 #elif defined(ARM_FPU_VFP)
                        ARM_CMPD (code, ins->sreg1, ins->sreg2);
+                       ARM_FMSTAT (code);
 #endif
                        ARM_MOV_REG_IMM8 (code, ins->dreg, 0);
                        ARM_MOV_REG_IMM8_COND (code, ins->dreg, 1, ARMCOND_MI);
@@ -3423,6 +3538,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        ARM_FCMP (code, ARM_FPA_CMF, ins->sreg2, ins->sreg1);
 #elif defined(ARM_FPU_VFP)
                        ARM_CMPD (code, ins->sreg2, ins->sreg1);
+                       ARM_FMSTAT (code);
 #endif
                        ARM_MOV_REG_IMM8 (code, ins->dreg, 0);
                        ARM_MOV_REG_IMM8_COND (code, ins->dreg, 1, ARMCOND_MI);
@@ -3433,6 +3549,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        ARM_FCMP (code, ARM_FPA_CMF, ins->sreg2, ins->sreg1);
 #elif defined(ARM_FPU_VFP)
                        ARM_CMPD (code, ins->sreg2, ins->sreg1);
+                       ARM_FMSTAT (code);
 #endif
                        ARM_MOV_REG_IMM8 (code, ins->dreg, 0);
                        ARM_MOV_REG_IMM8_COND (code, ins->dreg, 1, ARMCOND_MI);
@@ -3479,8 +3596,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
 #ifdef ARM_FPU_FPA
                        if (ins->dreg != ins->sreg1)
                                ARM_MVFD (code, ins->dreg, ins->sreg1);
-#else
-                       g_assert_not_reached ();
+#elif defined(ARM_FPU_VFP)
+                       ARM_CPYD (code, ins->dreg, ins->sreg1);
 #endif
                        break;
                }
@@ -3633,7 +3750,7 @@ mono_arch_emit_prolog (MonoCompile *cfg)
        CallInfo *cinfo;
        int tracing = 0;
        int lmf_offset = 0;
-       int prev_sp_offset;
+       int prev_sp_offset, reg_offset;
 
        if (mono_jit_trace_calls != NULL && mono_trace_eval (method))
                tracing = 1;
@@ -3642,22 +3759,40 @@ mono_arch_emit_prolog (MonoCompile *cfg)
        cfg->code_size = 256 + sig->param_count * 20;
        code = cfg->native_code = g_malloc (cfg->code_size);
 
+       mono_emit_unwind_op_def_cfa (cfg, code, ARMREG_SP, 0);
+
        ARM_MOV_REG_REG (code, ARMREG_IP, ARMREG_SP);
 
        alloc_size = cfg->stack_offset;
        pos = 0;
 
        if (!method->save_lmf) {
-               // FIXME: Why save IP ?
+               /* We save SP by storing it into IP and saving IP */
                ARM_PUSH (code, (cfg->used_int_regs | (1 << ARMREG_IP) | (1 << ARMREG_LR)));
                prev_sp_offset = 8; /* ip and lr */
                for (i = 0; i < 16; ++i) {
                        if (cfg->used_int_regs & (1 << i))
                                prev_sp_offset += 4;
                }
+               mono_emit_unwind_op_def_cfa_offset (cfg, code, prev_sp_offset);
+               reg_offset = 0;
+               for (i = 0; i < 16; ++i) {
+                       if ((cfg->used_int_regs & (1 << i)) || (i == ARMREG_IP) || (i == ARMREG_LR)) {
+                               mono_emit_unwind_op_offset (cfg, code, i, (- prev_sp_offset) + reg_offset);
+                               reg_offset += 4;
+                       }
+               }
        } else {
                ARM_PUSH (code, 0x5ff0);
                prev_sp_offset = 4 * 10; /* all but r0-r3, sp and pc */
+               mono_emit_unwind_op_def_cfa_offset (cfg, code, prev_sp_offset);
+               reg_offset = 0;
+               for (i = 0; i < 16; ++i) {
+                       if ((i > ARMREG_R3) && (i != ARMREG_SP) && (i != ARMREG_PC)) {
+                               mono_emit_unwind_op_offset (cfg, code, i, (- prev_sp_offset) + reg_offset);
+                               reg_offset += 4;
+                       }
+               }
                pos += sizeof (MonoLMF) - prev_sp_offset;
                lmf_offset = pos;
        }
@@ -3679,9 +3814,11 @@ mono_arch_emit_prolog (MonoCompile *cfg)
                        code = mono_arm_emit_load_imm (code, ARMREG_IP, alloc_size);
                        ARM_SUB_REG_REG (code, ARMREG_SP, ARMREG_SP, ARMREG_IP);
                }
+               mono_emit_unwind_op_def_cfa_offset (cfg, code, prev_sp_offset + alloc_size);
        }
        if (cfg->frame_reg != ARMREG_SP) {
                ARM_MOV_REG_REG (code, cfg->frame_reg, ARMREG_SP);
+               mono_emit_unwind_op_def_cfa_reg (cfg, code, cfg->frame_reg);
        }
        //g_print ("prev_sp_offset: %d, alloc_size:%d\n", prev_sp_offset, alloc_size);
        prev_sp_offset += alloc_size;
@@ -4165,9 +4302,6 @@ mono_arch_flush_register_windows (void)
 void
 mono_arch_fixup_jinfo (MonoCompile *cfg)
 {
-       /* max encoded stack usage is 64KB * 4 */
-       g_assert ((cfg->stack_usage & ~(0xffff << 2)) == 0);
-       cfg->jit_info->used_regs |= cfg->stack_usage << 14;
 }
 
 #ifdef MONO_ARCH_HAVE_IMT
@@ -4272,7 +4406,11 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
        size = BASE_SIZE;
        constant_pool_starts = g_new0 (guint32*, count);
 
-       g_assert (!fail_tramp);
+       /* 
+        * We might be called with a fail_tramp from the IMT builder code even if
+        * MONO_ARCH_HAVE_GENERALIZED_IMT_THUNK is not defined.
+        */
+       //g_assert (!fail_tramp);
 
        for (i = 0; i < count; ++i) {
                MonoIMTCheckItem *item = imt_entries [i];
@@ -4302,7 +4440,7 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
        if (large_offsets)
                size += 4 * count; /* The ARM_ADD_REG_IMM to pop the stack */
 
-       start = code = mono_code_manager_reserve (domain->code_mp, size);
+       start = code = mono_domain_code_reserve (domain, size);
 
 #if DEBUG_IMT
        printf ("building IMT thunk for class %s %s entries %d code size %d code at %p end %p vtable %p\n", vtable->klass->name_space, vtable->klass->name, count, size, start, ((guint8*)start) + size, vtable);