Add AOT support for GC inline write barriers.
authorZoltan Varga <vargaz@gmail.com>
Tue, 31 Aug 2010 14:12:36 +0000 (16:12 +0200)
committerZoltan Varga <vargaz@gmail.com>
Tue, 31 Aug 2010 14:12:36 +0000 (16:12 +0200)
mono/mini/aot-compiler.c
mono/mini/aot-runtime.c
mono/mini/method-to-ir.c
mono/mini/mini.c
mono/mini/patch-info.h

index 86ebb1dc28df93339857ebb631dc80d704447865..dcc8da17072f5af7d3cf250a0e7f06391367eb14 100644 (file)
@@ -3193,6 +3193,7 @@ encode_patch (MonoAotCompile *acfg, MonoJumpInfo *patch_info, guint8 *buf, guint
                encode_value (get_image_index (acfg, patch_info->data.image), p, &p);
                break;
        case MONO_PATCH_INFO_MSCORLIB_GOT_ADDR:
+       case MONO_PATCH_INFO_GC_CARD_TABLE_ADDR:
                break;
        case MONO_PATCH_INFO_METHOD_REL:
                encode_value ((gint)patch_info->data.offset, p, &p);
@@ -3394,6 +3395,12 @@ emit_method_info (MonoAotCompile *acfg, MonoCompile *cfg)
                        continue;
                }
 
+               if (patch_info->type == MONO_PATCH_INFO_GC_CARD_TABLE_ADDR) {
+                       /* Stored in a GOT slot initialized at module load time */
+                       patch_info->type = MONO_PATCH_INFO_NONE;
+                       continue;
+               }
+
                if (is_plt_patch (patch_info)) {
                        /* Calls are made through the PLT */
                        patch_info->type = MONO_PATCH_INFO_NONE;
@@ -4461,6 +4468,7 @@ compile_method (MonoAotCompile *acfg, MonoMethod *method)
                switch (patch_info->type) {
                case MONO_PATCH_INFO_GOT_OFFSET:
                case MONO_PATCH_INFO_NONE:
+               case MONO_PATCH_INFO_GC_CARD_TABLE_ADDR:
                        break;
                case MONO_PATCH_INFO_IMAGE:
                        /* The assembly is stored in GOT slot 0 */
@@ -6316,6 +6324,11 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options)
                ji = mono_mempool_alloc0 (acfg->mempool, sizeof (MonoAotCompile));
                ji->type = MONO_PATCH_INFO_MSCORLIB_GOT_ADDR;
                get_got_offset (acfg, ji);
+
+               /* This is very common */
+               ji = mono_mempool_alloc0 (acfg->mempool, sizeof (MonoAotCompile));
+               ji->type = MONO_PATCH_INFO_GC_CARD_TABLE_ADDR;
+               get_got_offset (acfg, ji);
        }
 
        TV_GETTIME (atv);
index 017cc083dd0b7bccdb91c5c195bb571ff0912ee4..40587fa14cdb55787a2be85f4ecdd61083880fc3 100644 (file)
@@ -1214,6 +1214,17 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
                }
        }
 
+#ifdef HAVE_SGEN_GC
+       {
+               MonoJumpInfo ji;
+
+               memset (&ji, 0, sizeof (ji));
+               ji.type = MONO_PATCH_INFO_GC_CARD_TABLE_ADDR;
+
+               amodule->got [2] = mono_resolve_patch_target (NULL, mono_get_root_domain (), NULL, &ji, FALSE);
+       }
+#endif
+
        /*
         * Since we store methoddef and classdef tokens when referring to methods/classes in
         * referenced assemblies, we depend on the exact versions of the referenced assemblies.
@@ -2276,6 +2287,7 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin
        case MONO_PATCH_INFO_GENERIC_CLASS_INIT:
        case MONO_PATCH_INFO_MONITOR_ENTER:
        case MONO_PATCH_INFO_MONITOR_EXIT:
+       case MONO_PATCH_INFO_GC_CARD_TABLE_ADDR:
                break;
        case MONO_PATCH_INFO_RGCTX_FETCH: {
                gboolean res;
index 4ff1be87bdbc62e682e58be0877fe5ca95b8f921..2fe09a9ddcd718f9a86bded140edd4bd20dc9d99 100644 (file)
@@ -2605,7 +2605,7 @@ emit_write_barrier (MonoCompile *cfg, MonoInst *ptr, MonoInst *value, int value_
 
        mono_gc_get_nursery (&nursery_shift_bits, &nursery_size);
 
-       if (card_table && nursery_shift_bits > 0) {
+       if (!cfg->compile_aot && card_table && nursery_shift_bits > 0) {
                MonoInst *wbarrier;
 
                MONO_INST_NEW (cfg, wbarrier, OP_CARD_TABLE_WBARRIER);
@@ -2629,10 +2629,14 @@ emit_write_barrier (MonoCompile *cfg, MonoInst *ptr, MonoInst *value, int value_
                /*We can't use PADD_IMM since the cardtable might end up in high addresses and amd64 doesn't support
                 * IMM's larger than 32bits.
                 */
-               MONO_INST_NEW (cfg, ins, OP_PCONST);
-               ins->inst_p0 = card_table;
-               ins->dreg = card_reg;
-               MONO_ADD_INS (cfg->cbb, ins);
+               if (cfg->compile_aot) {
+                       MONO_EMIT_NEW_AOTCONST (cfg, card_reg, NULL, MONO_PATCH_INFO_GC_CARD_TABLE_ADDR);
+               } else {
+                       MONO_INST_NEW (cfg, ins, OP_PCONST);
+                       ins->inst_p0 = card_table;
+                       ins->dreg = card_reg;
+                       MONO_ADD_INS (cfg->cbb, ins);
+               }
 
                MONO_EMIT_NEW_BIALU (cfg, OP_PADD, offset_reg, offset_reg, card_reg);
                MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STOREI1_MEMBASE_IMM, offset_reg, 0, 1);
index efd34543d98f8c355135c5b5e799993dc5aa8fa0..0f3d634d3fbaaafce450be4cfb418a2971477a8b 100644 (file)
@@ -3021,6 +3021,15 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code,
                g_assert_not_reached ();
 #endif
                break;
+#ifdef HAVE_SGEN_GC
+       case MONO_PATCH_INFO_GC_CARD_TABLE_ADDR: {
+               int card_table_shift_bits;
+               gpointer card_table_mask;
+
+               target = mono_gc_get_card_table (&card_table_shift_bits, &card_table_mask);
+               break;
+       }
+#endif
        default:
                g_assert_not_reached ();
        }
index a45f7bf3e3472f5b2b325d86a1951f8454f419b9..5e51ace6d82cd3aa30540403554e74124434b34f 100644 (file)
@@ -40,4 +40,5 @@ PATCH_INFO(MONITOR_EXIT, "monitor_exit")
 PATCH_INFO(MSCORLIB_GOT_ADDR, "mscorlib_got_addr")
 PATCH_INFO(SEQ_POINT_INFO, "seq_point_info")
 PATCH_INFO(LLVM_IMT_TRAMPOLINE, "llvm_imt_trampoline")
+PATCH_INFO(GC_CARD_TABLE_ADDR, "gc_card_table_addr")
 PATCH_INFO(NONE, "none")