Merge pull request #1659 from alexanderkyte/stringbuilder-referencesource
[mono.git] / mono / mini / mini-amd64.c
index 0a37908f2fb463afaaac995a8a27561908f3f280..1a31eab4d025032dbed313949f1e334befc62c40 100755 (executable)
@@ -594,8 +594,6 @@ merge_argument_class_from_type (MonoGenericSharingContext *gsctx, MonoType *type
 
        ptype = mini_type_get_underlying_type (gsctx, type);
        switch (ptype->type) {
-       case MONO_TYPE_BOOLEAN:
-       case MONO_TYPE_CHAR:
        case MONO_TYPE_I1:
        case MONO_TYPE_U1:
        case MONO_TYPE_I2:
@@ -751,7 +749,7 @@ add_valuetype (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, ArgIn
        klass = mono_class_from_mono_type (type);
        size = mini_type_stack_size_full (gsctx, &klass->byval_arg, NULL, sig->pinvoke);
 #ifndef HOST_WIN32
-       if (!sig->pinvoke && !disable_vtypes_in_regs && ((is_return && (size == 8)) || (!is_return && (size <= 16)))) {
+       if (!sig->pinvoke && ((is_return && (size == 8)) || (!is_return && (size <= 16)))) {
                /* We pass and return vtypes of size 8 in a register */
        } else if (!sig->pinvoke || (size == 0) || (size > 16)) {
                pass_on_stack = TRUE;
@@ -1011,73 +1009,69 @@ get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSign
 #endif
 
        /* return value */
-       {
-               ret_type = mini_type_get_underlying_type (gsctx, sig->ret);
-               switch (ret_type->type) {
-               case MONO_TYPE_BOOLEAN:
-               case MONO_TYPE_I1:
-               case MONO_TYPE_U1:
-               case MONO_TYPE_I2:
-               case MONO_TYPE_U2:
-               case MONO_TYPE_CHAR:
-               case MONO_TYPE_I4:
-               case MONO_TYPE_U4:
-               case MONO_TYPE_I:
-               case MONO_TYPE_U:
-               case MONO_TYPE_PTR:
-               case MONO_TYPE_FNPTR:
-               case MONO_TYPE_CLASS:
-               case MONO_TYPE_OBJECT:
-               case MONO_TYPE_SZARRAY:
-               case MONO_TYPE_ARRAY:
-               case MONO_TYPE_STRING:
-                       cinfo->ret.storage = ArgInIReg;
-                       cinfo->ret.reg = AMD64_RAX;
-                       break;
-               case MONO_TYPE_U8:
-               case MONO_TYPE_I8:
+       ret_type = mini_type_get_underlying_type (gsctx, sig->ret);
+       switch (ret_type->type) {
+       case MONO_TYPE_I1:
+       case MONO_TYPE_U1:
+       case MONO_TYPE_I2:
+       case MONO_TYPE_U2:
+       case MONO_TYPE_I4:
+       case MONO_TYPE_U4:
+       case MONO_TYPE_I:
+       case MONO_TYPE_U:
+       case MONO_TYPE_PTR:
+       case MONO_TYPE_FNPTR:
+       case MONO_TYPE_CLASS:
+       case MONO_TYPE_OBJECT:
+       case MONO_TYPE_SZARRAY:
+       case MONO_TYPE_ARRAY:
+       case MONO_TYPE_STRING:
+               cinfo->ret.storage = ArgInIReg;
+               cinfo->ret.reg = AMD64_RAX;
+               break;
+       case MONO_TYPE_U8:
+       case MONO_TYPE_I8:
+               cinfo->ret.storage = ArgInIReg;
+               cinfo->ret.reg = AMD64_RAX;
+               break;
+       case MONO_TYPE_R4:
+               cinfo->ret.storage = ArgInFloatSSEReg;
+               cinfo->ret.reg = AMD64_XMM0;
+               break;
+       case MONO_TYPE_R8:
+               cinfo->ret.storage = ArgInDoubleSSEReg;
+               cinfo->ret.reg = AMD64_XMM0;
+               break;
+       case MONO_TYPE_GENERICINST:
+               if (!mono_type_generic_inst_is_valuetype (ret_type)) {
                        cinfo->ret.storage = ArgInIReg;
                        cinfo->ret.reg = AMD64_RAX;
                        break;
-               case MONO_TYPE_R4:
-                       cinfo->ret.storage = ArgInFloatSSEReg;
-                       cinfo->ret.reg = AMD64_XMM0;
-                       break;
-               case MONO_TYPE_R8:
-                       cinfo->ret.storage = ArgInDoubleSSEReg;
-                       cinfo->ret.reg = AMD64_XMM0;
-                       break;
-               case MONO_TYPE_GENERICINST:
-                       if (!mono_type_generic_inst_is_valuetype (ret_type)) {
-                               cinfo->ret.storage = ArgInIReg;
-                               cinfo->ret.reg = AMD64_RAX;
-                               break;
-                       }
-                       /* fall through */
+               }
+               /* fall through */
 #if defined( __native_client_codegen__ )
-               case MONO_TYPE_TYPEDBYREF:
+       case MONO_TYPE_TYPEDBYREF:
 #endif
-               case MONO_TYPE_VALUETYPE: {
-                       guint32 tmp_gr = 0, tmp_fr = 0, tmp_stacksize = 0;
+       case MONO_TYPE_VALUETYPE: {
+               guint32 tmp_gr = 0, tmp_fr = 0, tmp_stacksize = 0;
 
-                       add_valuetype (gsctx, sig, &cinfo->ret, ret_type, TRUE, &tmp_gr, &tmp_fr, &tmp_stacksize);
-                       if (cinfo->ret.storage == ArgOnStack) {
-                               cinfo->vtype_retaddr = TRUE;
-                               /* The caller passes the address where the value is stored */
-                       }
-                       break;
+               add_valuetype (gsctx, sig, &cinfo->ret, ret_type, TRUE, &tmp_gr, &tmp_fr, &tmp_stacksize);
+               if (cinfo->ret.storage == ArgOnStack) {
+                       cinfo->vtype_retaddr = TRUE;
+                       /* The caller passes the address where the value is stored */
                }
+               break;
+       }
 #if !defined( __native_client_codegen__ )
-               case MONO_TYPE_TYPEDBYREF:
-                       /* Same as a valuetype with size 24 */
-                       cinfo->vtype_retaddr = TRUE;
-                       break;
+       case MONO_TYPE_TYPEDBYREF:
+               /* Same as a valuetype with size 24 */
+               cinfo->vtype_retaddr = TRUE;
+               break;
 #endif
-               case MONO_TYPE_VOID:
-                       break;
-               default:
-                       g_error ("Can't handle as return value 0x%x", ret_type->type);
-               }
+       case MONO_TYPE_VOID:
+               break;
+       default:
+               g_error ("Can't handle as return value 0x%x", ret_type->type);
        }
 
        pstart = 0;
@@ -1141,14 +1135,12 @@ get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSign
 
                ptype = mini_type_get_underlying_type (gsctx, sig->params [i]);
                switch (ptype->type) {
-               case MONO_TYPE_BOOLEAN:
                case MONO_TYPE_I1:
                case MONO_TYPE_U1:
                        add_general (&gr, &stack_size, ainfo);
                        break;
                case MONO_TYPE_I2:
                case MONO_TYPE_U2:
-               case MONO_TYPE_CHAR:
                        add_general (&gr, &stack_size, ainfo);
                        break;
                case MONO_TYPE_I4:
@@ -1250,7 +1242,7 @@ mono_arch_tail_call_supported (MonoCompile *cfg, MonoMethodSignature *caller_sig
        c1 = get_call_info (NULL, NULL, caller_sig);
        c2 = get_call_info (NULL, NULL, callee_sig);
        res = c1->stack_usage >= c2->stack_usage;
-       callee_ret = mini_replace_type (callee_sig->ret);
+       callee_ret = mini_get_underlying_type (cfg, callee_sig->ret);
        if (callee_ret && MONO_TYPE_ISSTRUCT (callee_ret) && c2->ret.storage != ArgValuetypeInReg)
                /* An address on the callee's stack is passed as the first argument */
                res = FALSE;
@@ -1649,17 +1641,14 @@ mono_arch_fill_argument_info (MonoCompile *cfg)
 {
        MonoType *sig_ret;
        MonoMethodSignature *sig;
-       MonoMethodHeader *header;
        MonoInst *ins;
        int i;
        CallInfo *cinfo;
 
-       header = cfg->header;
-
        sig = mono_method_signature (cfg->method);
 
        cinfo = cfg->arch.cinfo;
-       sig_ret = mini_replace_type (sig->ret);
+       sig_ret = mini_get_underlying_type (cfg, sig->ret);
 
        /*
         * Contrary to mono_arch_allocate_vars (), the information should describe
@@ -1693,15 +1682,9 @@ mono_arch_fill_argument_info (MonoCompile *cfg)
 
        for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
                ArgInfo *ainfo = &cinfo->args [i];
-               MonoType *arg_type;
 
                ins = cfg->args [i];
 
-               if (sig->hasthis && (i == 0))
-                       arg_type = &mono_defaults.object_class->byval_arg;
-               else
-                       arg_type = sig->params [i - sig->hasthis];
-
                switch (ainfo->storage) {
                case ArgInIReg:
                case ArgInFloatSSEReg:
@@ -1729,19 +1712,16 @@ mono_arch_allocate_vars (MonoCompile *cfg)
 {
        MonoType *sig_ret;
        MonoMethodSignature *sig;
-       MonoMethodHeader *header;
        MonoInst *ins;
        int i, offset;
        guint32 locals_stack_size, locals_stack_align;
        gint32 *offsets;
        CallInfo *cinfo;
 
-       header = cfg->header;
-
        sig = mono_method_signature (cfg->method);
 
        cinfo = cfg->arch.cinfo;
-       sig_ret = mini_replace_type (sig->ret);
+       sig_ret = mini_get_underlying_type (cfg, sig->ret);
 
        mono_arch_compute_omit_fp (cfg);
 
@@ -1885,12 +1865,6 @@ mono_arch_allocate_vars (MonoCompile *cfg)
                if (ins->opcode != OP_REGVAR) {
                        ArgInfo *ainfo = &cinfo->args [i];
                        gboolean inreg = TRUE;
-                       MonoType *arg_type;
-
-                       if (sig->hasthis && (i == 0))
-                               arg_type = &mono_defaults.object_class->byval_arg;
-                       else
-                               arg_type = sig->params [i - sig->hasthis];
 
                        if (cfg->globalra) {
                                /* The new allocator needs info about the original locations of the arguments */
@@ -2022,7 +1996,7 @@ mono_arch_create_vars (MonoCompile *cfg)
        if (cinfo->ret.storage == ArgValuetypeInReg)
                cfg->ret_var_is_local = TRUE;
 
-       sig_ret = mini_replace_type (sig->ret);
+       sig_ret = mini_get_underlying_type (cfg, sig->ret);
        if ((cinfo->ret.storage != ArgValuetypeInReg) && MONO_TYPE_ISSTRUCT (sig_ret)) {
                cfg->vret_addr = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_ARG);
                if (G_UNLIKELY (cfg->verbose_level > 1)) {
@@ -2141,6 +2115,7 @@ emit_sig_cookie (MonoCompile *cfg, MonoCallInst *call, CallInfo *cinfo)
        MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, AMD64_RSP, cinfo->sig_cookie.offset, sig_reg);
 }
 
+#ifdef ENABLE_LLVM
 static inline LLVMArgStorage
 arg_storage_to_llvm_arg_storage (MonoCompile *cfg, ArgStorage storage)
 {
@@ -2155,7 +2130,6 @@ arg_storage_to_llvm_arg_storage (MonoCompile *cfg, ArgStorage storage)
        }
 }
 
-#ifdef ENABLE_LLVM
 LLVMCallInfo*
 mono_arch_get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
 {
@@ -2167,7 +2141,7 @@ mono_arch_get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
        MonoType *t, *sig_ret;
 
        n = sig->param_count + sig->hasthis;
-       sig_ret = mini_replace_type (sig->ret);
+       sig_ret = mini_get_underlying_type (cfg, sig->ret);
 
        cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig);
 
@@ -2256,12 +2230,10 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
        MonoInst *arg, *in;
        MonoMethodSignature *sig;
        MonoType *sig_ret;
-       int i, n, stack_size;
+       int i, n;
        CallInfo *cinfo;
        ArgInfo *ainfo;
 
-       stack_size = 0;
-
        sig = call->signature;
        n = sig->param_count + sig->hasthis;
 
@@ -2290,6 +2262,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
                else
                        t = sig->params [i - sig->hasthis];
 
+               t = mini_get_underlying_type (cfg, t);
                if (ainfo->storage == ArgOnStack && !MONO_TYPE_ISSTRUCT (t) && !call->tail_call) {
                        if (!t->byref) {
                                if (t->type == MONO_TYPE_R4)
@@ -2398,7 +2371,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
        if (!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG) && (n == sig->sentinelpos))
                emit_sig_cookie (cfg, call, cinfo);
 
-       sig_ret = mini_replace_type (sig->ret);
+       sig_ret = mini_get_underlying_type (cfg, sig->ret);
        if (sig_ret && MONO_TYPE_ISSTRUCT (sig_ret)) {
                MonoInst *vtarg;
 
@@ -2533,7 +2506,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_replace_type (mono_method_signature (method)->ret);
+       MonoType *ret = mini_get_underlying_type (cfg, mono_method_signature (method)->ret);
 
        if (ret->type == MONO_TYPE_R4) {
                if (COMPILE_LLVM (cfg))
@@ -2706,7 +2679,7 @@ mono_arch_start_dyn_call (MonoDynCallInfo *info, gpointer **args, guint8 *ret, g
                p->regs [greg ++] = PTR_TO_GREG(ret);
 
        for (i = pindex; i < sig->param_count; i++) {
-               MonoType *t = mono_type_get_underlying_type (sig->params [i]);
+               MonoType *t = mini_type_get_underlying_type (NULL, sig->params [i]);
                gpointer *arg = args [arg_index ++];
 
                if (t->byref) {
@@ -2737,7 +2710,6 @@ mono_arch_start_dyn_call (MonoDynCallInfo *info, gpointer **args, guint8 *ret, g
                        p->regs [greg ++] = *(guint64*)(arg);
                        break;
 #endif
-               case MONO_TYPE_BOOLEAN:
                case MONO_TYPE_U1:
                        p->regs [greg ++] = *(guint8*)(arg);
                        break;
@@ -2748,7 +2720,6 @@ mono_arch_start_dyn_call (MonoDynCallInfo *info, gpointer **args, guint8 *ret, g
                        p->regs [greg ++] = *(gint16*)(arg);
                        break;
                case MONO_TYPE_U2:
-               case MONO_TYPE_CHAR:
                        p->regs [greg ++] = *(guint16*)(arg);
                        break;
                case MONO_TYPE_I4:
@@ -2802,7 +2773,7 @@ mono_arch_finish_dyn_call (MonoDynCallInfo *info, guint8 *buf)
        MonoMethodSignature *sig = dinfo->sig;
        guint8 *ret = ((DynCallArgs*)buf)->ret;
        mgreg_t res = ((DynCallArgs*)buf)->res;
-       MonoType *sig_ret = mono_type_get_underlying_type (sig->ret);
+       MonoType *sig_ret = mini_type_get_underlying_type (NULL, sig->ret);
 
        switch (sig_ret->type) {
        case MONO_TYPE_VOID:
@@ -2822,14 +2793,12 @@ mono_arch_finish_dyn_call (MonoDynCallInfo *info, guint8 *buf)
                *(gint8*)ret = res;
                break;
        case MONO_TYPE_U1:
-       case MONO_TYPE_BOOLEAN:
                *(guint8*)ret = res;
                break;
        case MONO_TYPE_I2:
                *(gint16*)ret = res;
                break;
        case MONO_TYPE_U2:
-       case MONO_TYPE_CHAR:
                *(guint16*)ret = res;
                break;
        case MONO_TYPE_I4:
@@ -3487,8 +3456,9 @@ emit_move_return_value (MonoCompile *cfg, MonoInst *ins, guint8 *code)
                break;
        case OP_FCALL:
        case OP_FCALL_REG:
-       case OP_FCALL_MEMBASE:
-               if (((MonoCallInst*)ins)->signature->ret->type == MONO_TYPE_R4) {
+       case OP_FCALL_MEMBASE: {
+               MonoType *rtype = mini_get_underlying_type (cfg, ((MonoCallInst*)ins)->signature->ret);
+               if (rtype->type == MONO_TYPE_R4) {
                        amd64_sse_cvtss2sd_reg_reg (code, ins->dreg, AMD64_XMM0);
                }
                else {
@@ -3496,6 +3466,7 @@ emit_move_return_value (MonoCompile *cfg, MonoInst *ins, guint8 *code)
                                amd64_sse_movsd_reg_reg (code, ins->dreg, AMD64_XMM0);
                }
                break;
+       }
        case OP_RCALL:
        case OP_RCALL_REG:
        case OP_RCALL_MEMBASE:
@@ -3549,7 +3520,7 @@ static int tls_gs_offset;
 gboolean
 mono_amd64_have_tls_get (void)
 {
-#ifdef __APPLE__
+#ifdef TARGET_MACH
        static gboolean have_tls_get = FALSE;
        static gboolean inited = FALSE;
        guint8 *ins;
@@ -3580,7 +3551,7 @@ mono_amd64_have_tls_get (void)
        tls_gs_offset = ins[5];
 
        return have_tls_get;
-#elif defined(PLATFORM_ANDROID)
+#elif defined(TARGET_ANDROID)
        return FALSE;
 #else
        return TRUE;
@@ -3781,8 +3752,6 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
        MonoCallInst *call;
        guint offset;
        guint8 *code = cfg->native_code + cfg->code_len;
-       MonoInst *last_ins = NULL;
-       guint last_offset = 0;
        int max_len;
 
        /* Fix max_offset estimate for each successor bb */
@@ -3825,7 +3794,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
        if (cfg->verbose_level > 2)
                g_print ("Basic block %d starting at offset 0x%x\n", bb->block_num, bb->native_offset);
 
-       if (cfg->prof_options & MONO_PROFILE_COVERAGE) {
+       if ((cfg->prof_options & MONO_PROFILE_COVERAGE) && cfg->coverage_info) {
                MonoProfileCoverageInfo *cov = cfg->coverage_info;
                g_assert (!cfg->compile_aot);
 
@@ -4442,9 +4411,6 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        amd64_shift_reg (code, X86_SAR, ins->dreg);
                        break;
                case OP_SHR_IMM:
-                       g_assert (amd64_is_imm32 (ins->inst_imm));
-                       amd64_shift_reg_imm_size (code, X86_SAR, ins->dreg, ins->inst_imm, 4);
-                       break;
                case OP_LSHR_IMM:
                        g_assert (amd64_is_imm32 (ins->inst_imm));
                        amd64_shift_reg_imm (code, X86_SAR, ins->dreg, ins->inst_imm);
@@ -4462,9 +4428,6 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        amd64_shift_reg (code, X86_SHR, ins->dreg);
                        break;
                case OP_SHL_IMM:
-                       g_assert (amd64_is_imm32 (ins->inst_imm));
-                       amd64_shift_reg_imm_size (code, X86_SHL, ins->dreg, ins->inst_imm, 4);
-                       break;
                case OP_LSHL_IMM:
                        g_assert (amd64_is_imm32 (ins->inst_imm));
                        amd64_shift_reg_imm (code, X86_SHL, ins->dreg, ins->inst_imm);
@@ -5737,8 +5700,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        guint32 size = ins->opcode == OP_ATOMIC_EXCHANGE_I4 ? 4 : 8;
 
                        /* LOCK prefix is implied. */
-                       amd64_xchg_membase_reg_size (code, ins->sreg1, ins->inst_offset, ins->sreg2, size);
-                       amd64_mov_reg_reg (code, ins->dreg, ins->sreg2, size);
+                       amd64_mov_reg_reg (code, GP_SCRATCH_REG, ins->sreg2, size);
+                       amd64_xchg_membase_reg_size (code, ins->sreg1, ins->inst_offset, GP_SCRATCH_REG, size);
+                       amd64_mov_reg_reg (code, ins->dreg, GP_SCRATCH_REG, size);
                        break;
                }
                case OP_ATOMIC_CAS_I4:
@@ -6596,9 +6560,6 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        g_assert_not_reached ();
 #endif
                }
-              
-               last_ins = ins;
-               last_offset = offset;
        }
 
        cfg->code_len = code - cfg->native_code;
@@ -7023,8 +6984,6 @@ mono_arch_emit_prolog (MonoCompile *cfg)
        /* Keep this in sync with emit_load_volatile_arguments */
        for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
                ArgInfo *ainfo = cinfo->args + i;
-               gint32 stack_offset;
-               MonoType *arg_type;
 
                ins = cfg->args [i];
 
@@ -7032,13 +6991,6 @@ mono_arch_emit_prolog (MonoCompile *cfg)
                        /* Unused arguments */
                        continue;
 
-               if (sig->hasthis && (i == 0))
-                       arg_type = &mono_defaults.object_class->byval_arg;
-               else
-                       arg_type = sig->params [i - sig->hasthis];
-
-               stack_offset = ainfo->offset + ARGS_OFFSET;
-
                if (cfg->globalra) {
                        /* All the other moves are done by the register allocator */
                        switch (ainfo->storage) {
@@ -7270,7 +7222,7 @@ void
 mono_arch_emit_epilog (MonoCompile *cfg)
 {
        MonoMethod *method = cfg->method;
-       int quad, pos, i;
+       int quad, i;
        guint8 *code;
        int max_epilog_size;
        CallInfo *cinfo;
@@ -7298,7 +7250,6 @@ mono_arch_emit_epilog (MonoCompile *cfg)
                code = mono_arch_instrument_epilog (cfg, mono_trace_leave_method, code, TRUE);
 
        /* the code restoring the registers must be kept in sync with OP_TAILCALL */
-       pos = 0;
        
        if (method->save_lmf) {
                /* check if we need to restore protection of the stack after a stack overflow */
@@ -7605,7 +7556,6 @@ void*
 mono_arch_instrument_prolog (MonoCompile *cfg, void *func, void *p, gboolean enable_arguments)
 {
        guchar *code = p;
-       CallInfo *cinfo = NULL;
        MonoMethodSignature *sig;
        MonoInst *inst;
        int i, n, stack_area = 0;
@@ -7616,8 +7566,6 @@ mono_arch_instrument_prolog (MonoCompile *cfg, void *func, void *p, gboolean ena
                /* Allocate a new area on the stack and save arguments there */
                sig = mono_method_signature (cfg->method);
 
-               cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig);
-
                n = sig->param_count + sig->hasthis;
 
                stack_area = ALIGN_TO (n * 8, 16);
@@ -7661,7 +7609,7 @@ mono_arch_instrument_epilog_full (MonoCompile *cfg, void *func, void *p, gboolea
        guchar *code = p;
        int save_mode = SAVE_NONE;
        MonoMethod *method = cfg->method;
-       MonoType *ret_type = mini_replace_type (mono_method_signature (method)->ret);
+       MonoType *ret_type = mini_get_underlying_type (cfg, mono_method_signature (method)->ret);
        int i;
        
        switch (ret_type->type) {
@@ -7877,8 +7825,6 @@ mono_arch_get_patch_offset (guint8 *code)
 gboolean
 mono_breakpoint_clean_code (guint8 *method_start, guint8 *code, int offset, guint8 *buf, int size)
 {
-       int i;
-       gboolean can_write = TRUE;
        /*
         * If method_start is non-NULL we need to perform bound checks, since we access memory
         * at code - offset we could go before the start of the method and end up in a different
@@ -7892,21 +7838,7 @@ mono_breakpoint_clean_code (guint8 *method_start, guint8 *code, int offset, guin
                memset (buf, 0, size);
                memcpy (buf + offset - diff, method_start, diff + size - offset);
        }
-       code -= offset;
-       for (i = 0; i < MONO_BREAKPOINT_ARRAY_SIZE; ++i) {
-               int idx = mono_breakpoint_info_index [i];
-               guint8 *ptr;
-               if (idx < 1)
-                       continue;
-               ptr = mono_breakpoint_info [idx].address;
-               if (ptr >= code && ptr < code + size) {
-                       guint8 saved_byte = mono_breakpoint_info [idx].saved_byte;
-                       can_write = FALSE;
-                       /*g_print ("patching %p with 0x%02x (was: 0x%02x)\n", ptr, saved_byte, buf [ptr - code]);*/
-                       buf [ptr - code] = saved_byte;
-               }
-       }
-       return can_write;
+       return TRUE;
 }
 
 #if defined(__native_client_codegen__)