Make GC maps for methods with finally clauses more precise.
authorZoltan Varga <vargaz@gmail.com>
Sat, 25 Sep 2010 15:29:37 +0000 (17:29 +0200)
committerZoltan Varga <vargaz@gmail.com>
Mon, 3 Jan 2011 14:42:35 +0000 (15:42 +0100)
mono/mini/mini-gc.c

index 37f7b8a16a91bfbe5d66b684bf651651da3de483..77eb013c8383a7d3291cff906b57e080518f9d70 100644 (file)
@@ -689,8 +689,11 @@ conservative_pass (TlsData *tls, guint8 *stack_start, guint8 *stack_end)
                        continue;
 
                /* These frames are very problematic */
-               if (ji->method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE)
+               if (ji->method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
+                       DEBUG (char *fname = mono_method_full_name (ji->method, TRUE); printf ("Mark(0): %s+0x%x (%p)\n", fname, pc_offset, (gpointer)MONO_CONTEXT_GET_IP (&ctx)); g_free (fname));
+                       DEBUG (printf ("\tSkip.\n"));
                        continue;
+               }
 
 #if 0
                /* FIXME: Some wrappers do not declare variables with the proper GC type */
@@ -844,8 +847,10 @@ conservative_pass (TlsData *tls, guint8 *stack_start, guint8 *stack_end)
                                if (!(map->reg_pin_mask & (1 << i)))
                                        continue;
 
-                               if (pin_bitmap [bindex / 8] & (1 << (bindex % 8)))
+                               if (pin_bitmap [bindex / 8] & (1 << (bindex % 8))) {
+                                       DEBUG (printf ("\treg %s saved at 0x%p is pinning.\n", mono_arch_regname (i), reg_locations [i]));
                                        precise_regmask &= ~(1 << i);
+                               }
                                bindex ++;
                        }
                }
@@ -1895,22 +1900,33 @@ create_map (MonoCompile *cfg)
                }
        }
        if (has_finally) {
-               /* Treat every slot which has a ref somewhere as pin everywhere */
+               /* Treat every slot which has a ref somewhere as pin outside its live range */
+               DEBUG (printf ("\tMethod has finally clauses, pessimizing live ranges.\n"));
                for (i = 0; i < nslots; ++i) {
                        for (j = 0; j < ncallsites; ++j) {
                                if (get_bit (gcfg->ref_bitmap, gcfg->bitmap_width, j, i))
                                        break;
                        }
-                       if (j < ncallsites)
-                               set_slot_everywhere (gcfg, i, SLOT_PIN);
+                       if (j < ncallsites) {
+                               for (j = 0; j < ncallsites; ++j) {
+                                       if (!get_bit (gcfg->ref_bitmap, gcfg->bitmap_width, j, i))
+                                               set_slot (gcfg, i, j, SLOT_PIN);
+                               }
+                               //set_slot_everywhere (gcfg, i, SLOT_PIN);
+                       }
                }
                for (i = 0; i < nregs; ++i) {
                        for (j = 0; j < ncallsites; ++j) {
                                if (get_bit (gcfg->reg_ref_bitmap, gcfg->reg_bitmap_width, j, i))
                                        break;
                        }
-                       if (j < ncallsites)
-                               set_reg_slot_everywhere (gcfg, i, SLOT_PIN);
+                       if (j < ncallsites) {
+                               for (j = 0; j < ncallsites; ++j) {
+                                       if (!get_bit (gcfg->reg_ref_bitmap, gcfg->reg_bitmap_width, j, i))
+                                               set_reg_slot (gcfg, i, j, SLOT_PIN);
+                               }
+                               //set_reg_slot_everywhere (gcfg, i, SLOT_PIN);
+                       }
                }
        }