* CodeGenerationOptions.cs: Made the class internal for the 1.1 profile.
[mono.git] / mono / mini / mini.c
index 3e8e5cd7ff3ad9f444e4f7e79f4714b03680e7b9..db0a95711d547cb53fd0f810cc2982f144ed572c 100644 (file)
@@ -92,11 +92,14 @@ static MonoMethodSignature *helper_sig_compile = NULL;
 static MonoMethodSignature *helper_sig_compile_virt = NULL;
 static MonoMethodSignature *helper_sig_obj_ptr = NULL;
 static MonoMethodSignature *helper_sig_obj_ptr_ptr = NULL;
+static MonoMethodSignature *helper_sig_obj_obj_ptr_ptr = NULL;
 static MonoMethodSignature *helper_sig_obj_void = NULL;
 static MonoMethodSignature *helper_sig_ptr_void = NULL;
+static MonoMethodSignature *helper_sig_void_void = NULL;
 static MonoMethodSignature *helper_sig_void_ptr = NULL;
 static MonoMethodSignature *helper_sig_void_obj = NULL;
 static MonoMethodSignature *helper_sig_void_obj_ptr_int = NULL;
+static MonoMethodSignature *helper_sig_void_obj_ptr_ptr_obj = NULL;
 static MonoMethodSignature *helper_sig_void_ptr_ptr = NULL;
 static MonoMethodSignature *helper_sig_void_ptr_ptr_ptr = NULL;
 static MonoMethodSignature *helper_sig_ptr_ptr_ptr = NULL;
@@ -1604,23 +1607,24 @@ mono_compile_get_interface_var (MonoCompile *cfg, int slot, MonoInst *ins)
  */
 static int
 handle_stack_args (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst **sp, int count) {
-       int i;
+       int i, bindex;
        MonoBasicBlock *outb;
        MonoInst *inst, **locals;
+       gboolean found;
 
        if (!count)
                return 0;
        if (cfg->verbose_level > 3)
                g_print ("%d item(s) on exit from B%d\n", count, bb->block_num);
        if (!bb->out_scount) {
-               int found = 0;
                bb->out_scount = count;
                //g_print ("bblock %d has out:", bb->block_num);
+               found = FALSE;
                for (i = 0; i < bb->out_count; ++i) {
                        outb = bb->out_bb [i];
                        //g_print (" %d", outb->block_num);
                        if (outb->in_stack) {
-                               found = 1;
+                               found = TRUE;
                                bb->out_stack = outb->in_stack;
                                break;
                        }
@@ -1629,19 +1633,34 @@ handle_stack_args (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst **sp, int coun
                if (!found) {
                        bb->out_stack = mono_mempool_alloc (cfg->mempool, sizeof (MonoInst*) * count);
                        for (i = 0; i < count; ++i) {
-/* see bug#58863, but removing this code causes regressions in gtk-sharp build 
- * (SEGV running Method::Initialize() in gapi_codegen.exe) 
- */
-#if 1
-                               /* try to reuse temps already allocated for this purpouse, if they occupy the same 
-                                * stack slot and if they are of the same type. */
-                               bb->out_stack [i] = mono_compile_get_interface_var (cfg, i, sp [i]);
-#else
-                               bb->out_stack [i] = mono_compile_create_var (cfg, type_from_stack_type (sp [i]), OP_LOCAL);
-#endif
+                               /* 
+                                * try to reuse temps already allocated for this purpouse, if they occupy the same
+                                * stack slot and if they are of the same type.
+                                * This won't cause conflicts since if 'local' is used to 
+                                * store one of the values in the in_stack of a bblock, then
+                                * the same variable will be used for the same outgoing stack 
+                                * slot as well. 
+                                * This doesn't work when inlining methods, since the bblocks
+                                * in the inlined methods do not inherit their in_stack from
+                                * the bblock they are inlined to. See bug #58863 for an
+                                * example.
+                                */
+                               if (cfg->inlined_method)
+                                       bb->out_stack [i] = mono_compile_create_var (cfg, type_from_stack_type (sp [i]), OP_LOCAL);
+                               else
+                                       bb->out_stack [i] = mono_compile_get_interface_var (cfg, i, sp [i]);
                        }
                }
        }
+
+       for (i = 0; i < bb->out_count; ++i) {
+               outb = bb->out_bb [i];
+               if (outb->in_scount)
+                       continue; /* check they are the same locals */
+               outb->in_scount = count;
+               outb->in_stack = bb->out_stack;
+       }
+
        locals = bb->out_stack;
        for (i = 0; i < count; ++i) {
                /* add store ops at the end of the bb, before the branch */
@@ -1656,14 +1675,36 @@ handle_stack_args (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst **sp, int coun
                if (cfg->verbose_level > 3)
                        g_print ("storing %d to temp %d\n", i, locals [i]->inst_c0);
        }
-       
-       for (i = 0; i < bb->out_count; ++i) {
-               outb = bb->out_bb [i];
-               if (outb->in_scount)
-                       continue; /* check they are the same locals */
-               outb->in_scount = count;
-               outb->in_stack = locals;
+
+       /*
+        * It is possible that the out bblocks already have in_stack assigned, and
+        * the in_stacks differ. In this case, we will store to all the different 
+        * in_stacks.
+        */
+
+       found = TRUE;
+       bindex = 0;
+       while (found) {
+               /* Find a bblock which has a different in_stack */
+               found = FALSE;
+               while (bindex < bb->out_count) {
+                       outb = bb->out_bb [bindex];
+                       if (outb->in_stack != locals) {
+                               /* 
+                                * Instead of storing sp [i] to locals [i], we need to store
+                                * locals [i] to <new locals>[i], since the sp [i] tree can't
+                                * be shared between trees.
+                                */
+                               for (i = 0; i < count; ++i)
+                                       mono_add_varcopy_to_end (cfg, bb, locals [i]->inst_c0, outb->in_stack [i]->inst_c0);
+                               locals = outb->in_stack;
+                               found = TRUE;
+                               break;
+                       }
+                       bindex ++;
+               }
        }
+       
        return 0;
 }
 
@@ -2245,7 +2286,8 @@ mono_method_check_inlining (MonoCompile *cfg, MonoMethod *method)
        int i;
 
 #ifdef MONO_ARCH_HAVE_LMF_OPS
-       if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) &&
+       if (((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
+                (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)) &&
            !MONO_TYPE_ISSTRUCT (signature->ret) && (method->klass->parent != mono_defaults.array_class))
                return TRUE;
 #endif
@@ -2461,6 +2503,7 @@ inline_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig,
        MonoMethodHeader *cheader;
        MonoBasicBlock *ebblock, *sbblock;
        int i, costs, new_locals_offset;
+       MonoMethod *prev_inlined_method;
 
        if (cfg->verbose_level > 2)
                g_print ("INLINE START %p %s -> %s\n", cmethod,  mono_method_full_name (cfg->method, TRUE), mono_method_full_name (cmethod, TRUE));
@@ -2489,8 +2532,13 @@ inline_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig,
        ebblock->block_num = cfg->num_bblocks++;
        ebblock->real_offset = real_offset;
 
+       prev_inlined_method = cfg->inlined_method;
+       cfg->inlined_method = cmethod;
+
        costs = mono_method_to_ir (cfg, cmethod, sbblock, ebblock, new_locals_offset, rvar, dont_inline, sp, real_offset, *ip == CEE_CALLVIRT);
 
+       cfg->inlined_method = prev_inlined_method;
+
        if ((costs >= 0 && costs < 60) || inline_allways) {
                if (cfg->verbose_level > 2)
                        g_print ("INLINE END %s -> %s\n", mono_method_full_name (cfg->method, TRUE), mono_method_full_name (cmethod, TRUE));
@@ -3232,12 +3280,19 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                 * We have the `constrained.' prefix opcode.
                                 */
                                if (constrained_call->valuetype && !cmethod->klass->valuetype) {
+                                       MonoInst *load;
                                        /*
                                         * The type parameter is instantiated as a valuetype,
                                         * but that type doesn't override the method we're
                                         * calling, so we need to box `this'.
+                                        * sp [0] is a pointer to the data: we need the value
+                                        * in handle_box (), so load it here.
                                         */
-                                       sp [0] = handle_box (cfg, bblock, sp [0], ip, constrained_call);
+                                       MONO_INST_NEW (cfg, load, mono_type_to_ldind (&constrained_call->byval_arg));
+                                       type_to_eval_stack_type (&constrained_call->byval_arg, load);
+                                       load->cil_code = ip;
+                                       load->inst_left = sp [0];
+                                       sp [0] = handle_box (cfg, bblock, load, ip, constrained_call);
                                } else if (!constrained_call->valuetype) {
                                        MonoInst *ins;
 
@@ -3314,11 +3369,15 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                 !g_list_find (dont_inline, cmethod)) {
                                int costs;
                                MonoBasicBlock *ebblock;
+                               gboolean allways = FALSE;
 
-                               if (cmethod->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)
+                               if ((cmethod->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
+                                       (cmethod->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)) {
                                        cmethod = mono_marshal_get_native_wrapper (cmethod);
+                                       allways = TRUE;
+                               }
 
-                               if ((costs = inline_method (cfg, cmethod, fsig, bblock, sp, ip, real_offset, dont_inline, &ebblock, FALSE))) {
+                               if ((costs = inline_method (cfg, cmethod, fsig, bblock, sp, ip, real_offset, dont_inline, &ebblock, allways))) {
                                        ip += 5;
                                        real_offset += 5;
 
@@ -4777,14 +4836,15 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                        klass = mono_class_get_full (image, token, generic_context);
                        mono_class_init (klass);
                        if (MONO_TYPE_IS_REFERENCE (&klass->byval_arg)) {
+                               MonoMethod* helper = mono_marshal_get_stelemref ();
                                MonoInst *iargs [3];
                                handle_loaded_temps (cfg, bblock, stack_start, sp);
 
                                iargs [2] = sp [2];
                                iargs [1] = sp [1];
                                iargs [0] = sp [0];
-                       
-                               mono_emit_jit_icall (cfg, bblock, helper_stelem_ref, iargs, ip);
+                               
+                               mono_emit_method_call_spilled (cfg, bblock, helper, helper->signature, iargs, ip, NULL);
                        } else {
                                NEW_LDELEMA (cfg, load, sp, klass);
                                load->cil_code = ip;
@@ -4807,6 +4867,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                }
                case CEE_STELEM_REF: {
                        MonoInst *iargs [3];
+                       MonoMethod* helper = mono_marshal_get_stelemref ();
 
                        CHECK_STACK (3);
                        sp -= 3;
@@ -4817,7 +4878,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                        iargs [1] = sp [1];
                        iargs [0] = sp [0];
                        
-                       mono_emit_jit_icall (cfg, bblock, helper_stelem_ref, iargs, ip);
+                       mono_emit_method_call_spilled (cfg, bblock, helper, helper->signature, iargs, ip, NULL);
 
                        /*
                        MonoInst *group;
@@ -5089,158 +5150,30 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                        CHECK_OPSIZE (2);
                        switch (ip [1]) {
 
-                       case CEE_MONO_FUNC1: {
+                       case CEE_MONO_ICALL: {
                                int temp;
-                               gpointer func = NULL;
-                               CHECK_STACK (1);
-                               sp--;
+                               gpointer func;
+                               MonoJitICallInfo *info;
 
-                               CHECK_OPSIZE (3);
-                               switch (ip [2]) {
-                               case MONO_MARSHAL_CONV_STR_LPWSTR:
-                                       func = mono_string_to_utf16;
-                                       break;
-                               case MONO_MARSHAL_CONV_LPWSTR_STR:
-                                       func = mono_string_from_utf16;
-                                       break;
-                               case MONO_MARSHAL_CONV_LPSTR_STR:
-                                       func = mono_string_new_wrapper;
-                                       break;
-                               case MONO_MARSHAL_CONV_STR_LPTSTR:
-                               case MONO_MARSHAL_CONV_STR_LPSTR:
-                                       func = mono_string_to_utf8;
-                                       break;
-                               case MONO_MARSHAL_CONV_STR_BSTR:
-                                       func = mono_string_to_bstr;
-                                       break;
-                               case MONO_MARSHAL_CONV_STR_TBSTR:
-                               case MONO_MARSHAL_CONV_STR_ANSIBSTR:
-                                       func = mono_string_to_ansibstr;
-                                       break;
-                               case MONO_MARSHAL_CONV_SB_LPSTR:
-                               case MONO_MARSHAL_CONV_SB_LPTSTR:
-                                       func = mono_string_builder_to_utf8;
-                                       break;
-                               case MONO_MARSHAL_CONV_SB_LPWSTR:
-                                       func = mono_string_builder_to_utf16;
-                                       break;
-                               case MONO_MARSHAL_CONV_ARRAY_SAVEARRAY:
-                                       func = mono_array_to_savearray;
-                                       break;
-                               case MONO_MARSHAL_CONV_ARRAY_LPARRAY:
-                                       func = mono_array_to_lparray;
-                                       break;
-                               case MONO_MARSHAL_CONV_DEL_FTN:
-                                       func = mono_delegate_to_ftnptr;
-                                       break;
-                               case MONO_MARSHAL_CONV_STRARRAY_STRLPARRAY:
-                                       func = mono_marshal_string_array;
-                                       break;
-                               case MONO_MARSHAL_CONV_STRARRAY_STRWLPARRAY:
-                                       func = mono_marshal_string_array_to_unicode;
-                                       break;
-                               default:
-                                       g_warning ("unknown conversion %d\n", ip [2]);
-                                       g_assert_not_reached ();
-                               }
-
-                               temp = mono_emit_jit_icall (cfg, bblock, func, sp, ip);
-                               NEW_TEMPLOAD (cfg, *sp, temp);
-                               sp++;
-
-                               ip += 3;
-                               inline_costs += 10 * num_calls++;
-                               break;
-                       }
-
-                       case CEE_MONO_FUNC2: {
-                               int temp;
-                               gpointer func = NULL;
-                               CHECK_STACK (2);
-                               sp -= 2;
-
-                               CHECK_OPSIZE (3);
-                               switch (ip [2]) {
-                               case MONO_MARSHAL_CONV_ASANY:
-                                       func = mono_marshal_asany;
-                                       break;
-                               case MONO_MARSHAL_CONV_FTN_DEL:
-                                       func = mono_ftnptr_to_delegate;
-                                       break;
-                               default:
-                                       g_warning ("unknown conversion %d\n", ip [2]);
-                                       g_assert_not_reached ();
-                               }
-                               temp = mono_emit_jit_icall (cfg, bblock, func, sp, ip);
-                               NEW_TEMPLOAD (cfg, *sp, temp);
-                               sp++;
-
-                               ip += 3;
-                               inline_costs += 10 * num_calls++;
-                               break;
-                       }
+                               token = read32 (ip + 2);
+                               func = mono_method_get_wrapper_data (method, token);
+                               info = mono_find_jit_icall_by_addr (func);
+                               g_assert (info);
 
-                       case CEE_MONO_PROC2: {
-                               gpointer func = NULL;
-                               CHECK_STACK (2);
-                               sp -= 2;
+                               CHECK_STACK (info->sig->param_count);
+                               sp -= info->sig->param_count;
 
-                               CHECK_OPSIZE (3);
-                               switch (ip [2]) {
-                               case MONO_MARSHAL_CONV_LPSTR_SB:
-                               case MONO_MARSHAL_CONV_LPTSTR_SB:
-                                       func = mono_string_utf8_to_builder;
-                                       break;
-                               case MONO_MARSHAL_CONV_LPWSTR_SB:
-                                       func = mono_string_utf16_to_builder;
-                                       break;
-                               case MONO_MARSHAL_FREE_ARRAY:
-                                       func = mono_marshal_free_array;
-                                       break;
-                               case MONO_MARSHAL_CONV_ASANY:
-                                       func = mono_marshal_asany;
-                                       break;
-                               default:
-                                       g_assert_not_reached ();
+                               temp = mono_emit_jit_icall (cfg, bblock, info->func, sp, ip);
+                               if (!MONO_TYPE_IS_VOID (info->sig->ret)) {
+                                       NEW_TEMPLOAD (cfg, *sp, temp);
+                                       sp++;
                                }
 
-                               mono_emit_jit_icall (cfg, bblock, func, sp, ip);
-                               ip += 3;
+                               ip += 6;
                                inline_costs += 10 * num_calls++;
-                               break;
-                       }
-                       case CEE_MONO_PROC3: {
-                               gpointer func = NULL;
-                               CHECK_STACK (3);
-                               sp -= 3;
 
-                               CHECK_OPSIZE (3);
-                               switch (ip [2]) {
-                               case MONO_MARSHAL_CONV_STR_BYVALSTR:
-                                       func = mono_string_to_byvalstr;
-                                       break;
-                               case MONO_MARSHAL_CONV_STR_BYVALWSTR:
-                                       func = mono_string_to_byvalwstr;
-                                       break;
-                               case MONO_MARSHAL_FREE_ASANY:
-                                       func = mono_marshal_free_asany;
-                                       break;
-                               default:
-                                       g_assert_not_reached ();
-                               }
-
-                               mono_emit_jit_icall (cfg, bblock, func, sp, ip);
-                               ip += 3;
-                               inline_costs += 10 * num_calls++;
                                break;
                        }
-                       case CEE_MONO_FREE:
-                               CHECK_STACK (1);
-                               sp -= 1;
-                               mono_emit_jit_icall (cfg, bblock, g_free, sp, ip);
-                               ip += 2;
-                               inline_costs += 10 * num_calls++;
-                               break;
                        case CEE_MONO_LDPTR:
                                CHECK_STACK_OVF (1);
                                CHECK_OPSIZE (6);
@@ -5975,81 +5908,11 @@ mono_print_tree_nl (MonoInst *tree)
        printf ("\n");
 }
 
-static MonoType*
-type_from_typename (char *typename)
-{
-       MonoClass *klass;
-
-       if (!strcmp (typename, "int"))
-               klass = mono_defaults.int_class;
-       else if (!strcmp (typename, "ptr"))
-               klass = mono_defaults.int_class;
-       else if (!strcmp (typename, "void"))
-               klass = mono_defaults.void_class;
-       else if (!strcmp (typename, "int32"))
-               klass = mono_defaults.int32_class;
-       else if (!strcmp (typename, "uint32"))
-               klass = mono_defaults.uint32_class;
-       else if (!strcmp (typename, "long"))
-               klass = mono_defaults.int64_class;
-       else if (!strcmp (typename, "ulong"))
-               klass = mono_defaults.uint64_class;
-       else if (!strcmp (typename, "float"))
-               klass = mono_defaults.single_class;
-       else if (!strcmp (typename, "double"))
-               klass = mono_defaults.double_class;
-       else if (!strcmp (typename, "object"))
-               klass = mono_defaults.object_class;
-       else {
-               g_error (typename);
-               g_assert_not_reached ();
-       }
-       return &klass->byval_arg;
-}
-
-static MonoMethodSignature*
-make_icall_sig (const char *sigstr)
-{
-       gchar **parts;
-       int i, len;
-       gchar **tmp;
-       MonoMethodSignature *res;
-
-       parts = g_strsplit (sigstr, " ", 256);
-
-       tmp = parts;
-       len = 0;
-       while (*tmp) {
-               len ++;
-               tmp ++;
-       }
-
-       res = mono_metadata_signature_alloc (mono_defaults.corlib, len - 1);
-       res->pinvoke = 1;
-
-#ifdef PLATFORM_WIN32
-       /* 
-        * Under windows, the default pinvoke calling convention is STDCALL but
-        * we need CDECL.
-        */
-       res->call_convention = MONO_CALL_C;
-#endif
-
-       res->ret = type_from_typename (parts [0]);
-       for (i = 1; i < len; ++i) {
-               res->params [i - 1] = type_from_typename (parts [i]);
-       }
-
-       g_strfreev (parts);
-
-       return res;
-}
+#define make_icall_sig mono_create_icall_signature
 
 static void
 create_helper_signature (void)
 {
-
-       /* FIXME: set call conv */
        /* MonoArray * mono_array_new (MonoDomain *domain, MonoClass *klass, gint32 len) */
        helper_sig_newarr = make_icall_sig ("object ptr ptr int32");
 
@@ -6088,6 +5951,10 @@ create_helper_signature (void)
 
        helper_sig_obj_ptr_ptr = make_icall_sig ("object ptr ptr");
 
+       helper_sig_obj_obj_ptr_ptr = make_icall_sig ("object object ptr ptr");
+
+       helper_sig_void_void = make_icall_sig ("void");
+
        /* void amethod (intptr) */
        helper_sig_void_ptr = make_icall_sig ("void ptr");
 
@@ -6097,6 +5964,8 @@ create_helper_signature (void)
        /* void amethod (MonoObject *obj, void *ptr, int i) */
        helper_sig_void_obj_ptr_int = make_icall_sig ("void object ptr int");
 
+       helper_sig_void_obj_ptr_ptr_obj = make_icall_sig ("void object ptr ptr object");
+
        /* intptr amethod (void) */
        helper_sig_ptr_void = make_icall_sig ("ptr");
 
@@ -6160,35 +6029,6 @@ create_helper_signature (void)
        helper_sig_class_init_trampoline = make_icall_sig ("void");
 }
 
-static GHashTable *jit_icall_hash_name = NULL;
-static GHashTable *jit_icall_hash_addr = NULL;
-
-MonoJitICallInfo *
-mono_find_jit_icall_by_name (const char *name)
-{
-       MonoJitICallInfo *info;
-       g_assert (jit_icall_hash_name);
-
-       //printf ("lookup addr %s %p\n", name, g_hash_table_lookup (jit_icall_hash_name, name));
-       EnterCriticalSection (&trampoline_hash_mutex);
-       info = g_hash_table_lookup (jit_icall_hash_name, name);
-       LeaveCriticalSection (&trampoline_hash_mutex);
-       return info;
-}
-
-MonoJitICallInfo *
-mono_find_jit_icall_by_addr (gconstpointer addr)
-{
-       MonoJitICallInfo *info;
-       g_assert (jit_icall_hash_addr);
-
-       EnterCriticalSection (&trampoline_hash_mutex);
-       info = g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
-       LeaveCriticalSection (&trampoline_hash_mutex);
-
-       return info;
-}
-
 gconstpointer
 mono_icall_get_wrapper (MonoJitICallInfo* callinfo)
 {
@@ -6204,56 +6044,16 @@ mono_icall_get_wrapper (MonoJitICallInfo* callinfo)
        /* Must be domain neutral since there is only one copy */
        code = mono_jit_compile_method_with_opt (wrapper, default_opt | MONO_OPT_SHARED);
 
-       EnterCriticalSection (&trampoline_hash_mutex);
        if (!callinfo->wrapper) {
                callinfo->wrapper = code;
-               g_hash_table_insert (jit_icall_hash_addr, (gpointer)callinfo->wrapper, callinfo);
+               mono_register_jit_icall_wrapper (callinfo, code);
+               mono_debug_add_icall_wrapper (wrapper, callinfo);
        }
-       LeaveCriticalSection (&trampoline_hash_mutex);
 
        g_free (name);
        return callinfo->wrapper;
 }
 
-MonoJitICallInfo *
-mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
-{
-       MonoJitICallInfo *info;
-       
-       g_assert (func);
-       g_assert (name);
-
-       EnterCriticalSection (&trampoline_hash_mutex);
-
-       if (!jit_icall_hash_name) {
-               jit_icall_hash_name = g_hash_table_new (g_str_hash, g_str_equal);
-               jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
-       }
-
-       if (g_hash_table_lookup (jit_icall_hash_name, name)) {
-               g_warning ("jit icall already defined \"%s\"\n", name);
-               g_assert_not_reached ();
-       }
-
-       info = g_new (MonoJitICallInfo, 1);
-       
-       info->name = name;
-       info->func = func;
-       info->sig = sig;
-
-       if (is_save) {
-               info->wrapper = func;
-       } else {
-               info->wrapper = NULL;
-       }
-
-       g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
-       g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
-
-       LeaveCriticalSection (&trampoline_hash_mutex);
-       return info;
-}
-
 gpointer
 mono_create_class_init_trampoline (MonoVTable *vtable)
 {
@@ -6447,7 +6247,7 @@ print_dfn (MonoCompile *cfg) {
 
        for (i = 0; i < cfg->num_bblocks; ++i) {
                bb = cfg->bblocks [i];
-               if (bb->cil_code) {
+               /*if (bb->cil_code) {
                        char* code1, *code2;
                        code1 = mono_disasm_code_one (NULL, cfg->method, bb->cil_code, NULL);
                        if (bb->last_ins->cil_code)
@@ -6459,7 +6259,7 @@ print_dfn (MonoCompile *cfg) {
                        code = g_strdup_printf ("%s -> %s", code1, code2);
                        g_free (code1);
                        g_free (code2);
-               } else
+               } else*/
                        code = g_strdup ("\n");
                g_print ("\nBB%d DFN%d (len: %d): %s", bb->block_num, i, bb->cil_length, code);
                if (bb->code) {
@@ -8411,6 +8211,9 @@ mini_init (const char *filename)
        mono_register_jit_icall (mono_arch_get_throw_exception_by_name (), "mono_arch_throw_exception_by_name", 
                                 helper_sig_void_ptr, TRUE);
        mono_register_jit_icall (mono_thread_get_pending_exception, "mono_thread_get_pending_exception", helper_sig_obj_void, FALSE);
+       mono_register_jit_icall (mono_thread_interruption_checkpoint, "mono_thread_interruption_checkpoint", helper_sig_void_void, FALSE);
+       mono_register_jit_icall (mono_load_remote_field_new, "mono_load_remote_field_new", helper_sig_obj_obj_ptr_ptr, FALSE);
+       mono_register_jit_icall (mono_store_remote_field_new, "mono_store_remote_field_new", helper_sig_void_obj_ptr_ptr_obj, FALSE);
 
        /* 
         * NOTE, NOTE, NOTE, NOTE:
@@ -8479,28 +8282,6 @@ mini_init (const char *filename)
        mono_register_jit_icall (mono_object_new_fast, "mono_object_new_fast", helper_sig_object_new_specific, FALSE);
        mono_register_jit_icall (mono_array_new, "mono_array_new", helper_sig_newarr, FALSE);
        mono_register_jit_icall (mono_array_new_specific, "mono_array_new_specific", helper_sig_newarr_specific, FALSE);
-       mono_register_jit_icall (mono_string_to_utf16, "mono_string_to_utf16", helper_sig_ptr_obj, FALSE);
-       mono_register_jit_icall (mono_string_from_utf16, "mono_string_from_utf16", helper_sig_obj_ptr, FALSE);
-       mono_register_jit_icall (mono_string_new_wrapper, "mono_string_new_wrapper", helper_sig_obj_ptr, FALSE);
-       mono_register_jit_icall (mono_string_to_utf8, "mono_string_to_utf8", helper_sig_ptr_obj, FALSE);
-       mono_register_jit_icall (mono_string_to_bstr, "mono_string_to_bstr", helper_sig_ptr_obj, FALSE);
-       mono_register_jit_icall (mono_string_to_ansibstr, "mono_string_to_ansibstr", helper_sig_ptr_obj, FALSE);
-       mono_register_jit_icall (mono_string_builder_to_utf8, "mono_string_builder_to_utf8", helper_sig_ptr_obj, FALSE);
-       mono_register_jit_icall (mono_string_builder_to_utf16, "mono_string_builder_to_utf16", helper_sig_ptr_obj, FALSE);
-       mono_register_jit_icall (mono_array_to_savearray, "mono_array_to_savearray", helper_sig_ptr_obj, FALSE);
-       mono_register_jit_icall (mono_array_to_lparray, "mono_array_to_lparray", helper_sig_ptr_obj, FALSE);
-       mono_register_jit_icall (mono_delegate_to_ftnptr, "mono_delegate_to_ftnptr", helper_sig_ptr_obj, FALSE);
-       mono_register_jit_icall (mono_ftnptr_to_delegate, "mono_ftnptr_to_delegate", helper_sig_obj_ptr_ptr, FALSE);
-       mono_register_jit_icall (mono_marshal_string_array, "mono_marshal_string_array", helper_sig_ptr_obj, FALSE);
-       mono_register_jit_icall (mono_marshal_string_array_to_unicode, "mono_marshal_string_array_to_unicode", helper_sig_ptr_obj, FALSE);
-       mono_register_jit_icall (mono_marshal_asany, "mono_marshal_asany", helper_sig_ptr_obj_int, FALSE);
-       mono_register_jit_icall (mono_marshal_free_asany, "mono_marshal_free_asany", helper_sig_void_obj_ptr_int, FALSE);
-       mono_register_jit_icall (mono_string_utf8_to_builder, "mono_string_utf8_to_builder", helper_sig_void_ptr_ptr, FALSE);
-       mono_register_jit_icall (mono_string_utf16_to_builder, "mono_string_utf16_to_builder", helper_sig_void_ptr_ptr, FALSE);
-       mono_register_jit_icall (mono_marshal_free_array, "mono_marshal_free_array", helper_sig_void_ptr_ptr, FALSE);
-       mono_register_jit_icall (mono_string_to_byvalstr, "mono_string_to_byvalstr", helper_sig_void_ptr_ptr_ptr, FALSE);
-       mono_register_jit_icall (mono_string_to_byvalwstr, "mono_string_to_byvalwstr", helper_sig_void_ptr_ptr_ptr, FALSE);
-       mono_register_jit_icall (g_free, "g_free", helper_sig_void_ptr, FALSE);
        mono_register_jit_icall (mono_runtime_class_init, "mono_runtime_class_init", helper_sig_void_ptr, FALSE);
        mono_register_jit_icall (mono_ldftn, "mono_ldftn", helper_sig_compile, FALSE);
        mono_register_jit_icall (mono_ldftn_nosync, "mono_ldftn_nosync", helper_sig_compile, FALSE);