[jit] Implement OP_CARD_TABLE_WBARRIER on ios.
authorZoltan Varga <vargaz@gmail.com>
Wed, 5 Feb 2014 15:40:20 +0000 (16:40 +0100)
committerZoltan Varga <vargaz@gmail.com>
Wed, 5 Feb 2014 15:40:31 +0000 (16:40 +0100)
mono/mini/aot-compiler.c
mono/mini/aot-runtime.c
mono/mini/cpu-arm.md
mono/mini/method-to-ir.c
mono/mini/mini-arm.c
mono/mini/mini-arm.h
mono/mini/mini.c
mono/mini/patch-info.h

index 6b8f3244ce5e31a17fc7cd820be4cdb6ebf520b2..1849b816a7fc28e7c36d4b06c709e9f4e6e58d18 100644 (file)
@@ -4875,6 +4875,8 @@ encode_patch (MonoAotCompile *acfg, MonoJumpInfo *patch_info, guint8 *buf, guint
        case MONO_PATCH_INFO_JIT_TLS_ID:
        case MONO_PATCH_INFO_GC_CARD_TABLE_ADDR:
        case MONO_PATCH_INFO_CASTCLASS_CACHE:
+       case MONO_PATCH_INFO_NURSERY_START_SHIFTED:
+       case MONO_PATCH_INFO_NURSERY_SHIFT:
                break;
        case MONO_PATCH_INFO_METHOD_REL:
                encode_value ((gint)patch_info->data.offset, p, &p);
index 51577f520cea1f45e4df06e12f873e1f19dd5dd0..cdc6361e28bbdc1ae1c077ed553bb63655493e5a 100644 (file)
@@ -3079,6 +3079,8 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin
        case MONO_PATCH_INFO_GC_CARD_TABLE_ADDR:
        case MONO_PATCH_INFO_CASTCLASS_CACHE:
        case MONO_PATCH_INFO_JIT_TLS_ID:
+       case MONO_PATCH_INFO_NURSERY_START_SHIFTED:
+       case MONO_PATCH_INFO_NURSERY_SHIFT:
                break;
        case MONO_PATCH_INFO_RGCTX_FETCH: {
                gboolean res;
index b00f5647876ea9cfa334463decabca8912031ce0..b536e33692ee9d51bd73545d89fdf6d79b9af9d4 100644 (file)
@@ -334,3 +334,4 @@ gc_liveness_def: len:0
 gc_liveness_use: len:0
 gc_spill_slot_liveness_def: len:0
 gc_param_slot_liveness_def: len:0
+card_table_wbarrier: src1:i src2:i len:96
index 6e1050310a1ec7bc2d5543351cdf5db5078fe9f9..b53baa6ce14a76363760004514e8b334ff9b32e4 100644 (file)
@@ -2911,11 +2911,15 @@ emit_write_barrier (MonoCompile *cfg, MonoInst *ptr, MonoInst *value)
 
        mono_gc_get_nursery (&nursery_shift_bits, &nursery_size);
 
+#ifdef MONO_ARCH_HAVE_CARD_TABLE_WBARRIER_IN_AOT
+       if (cfg->compile_aot)
+               has_card_table_wb = TRUE;
+#endif
 #ifdef MONO_ARCH_HAVE_CARD_TABLE_WBARRIER
        has_card_table_wb = TRUE;
 #endif
 
-       if (has_card_table_wb && !cfg->compile_aot && card_table && nursery_shift_bits > 0 && !COMPILE_LLVM (cfg)) {
+       if (has_card_table_wb && card_table && nursery_shift_bits > 0 && !COMPILE_LLVM (cfg)) {
                MonoInst *wbarrier;
 
                MONO_INST_NEW (cfg, wbarrier, OP_CARD_TABLE_WBARRIER);
index 41edb9853b2e83635b0722475d5e7b0410b02b02..faa55d84bbc41be606d9af2cafc395dbc66e7175 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <mono/metadata/appdomain.h>
 #include <mono/metadata/debug-helpers.h>
+#include <mono/metadata/gc-internal.h>
 #include <mono/utils/mono-mmap.h>
 #include <mono/utils/mono-hwcap-arm.h>
 
@@ -372,6 +373,21 @@ mono_arm_load_jumptable_entry (guint8 *code, gpointer* jte, ARMReg reg)
 }
 #endif
 
+static guint8*
+emit_aotconst (MonoCompile *cfg, guint8 *start, guint8 *code, int dreg, int tramp_type, gconstpointer target)
+{
+       /* Load the GOT offset */
+       mono_add_patch_info (cfg, code - start, tramp_type, target);
+       ARM_LDR_IMM (code, dreg, ARMREG_PC, 0);
+       ARM_B (code, 0);
+       *(gpointer*)code = NULL;
+       code += 4;
+       /* Load the value from the GOT */
+       ARM_LDR_REG_REG (code, dreg, ARMREG_PC, dreg);
+
+       return code;
+}
+
 static guint8*
 emit_move_return_value (MonoCompile *cfg, MonoInst *ins, guint8 *code)
 {
@@ -4008,6 +4024,40 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        g_assert_not_reached ();
 #endif
                        break;
+               case OP_CARD_TABLE_WBARRIER: {
+                       int card_table_shift;
+                       gpointer card_table_mask;
+                       gboolean card_table_nursery_check = mono_gc_card_table_nursery_check ();
+                       int ptr = ins->sreg1;
+                       int value = ins->sreg2;
+                       guint8 *br = NULL;
+
+                       mono_gc_get_card_table (&card_table_shift, &card_table_mask);
+
+                       if (card_table_nursery_check) {
+                               code = emit_aotconst (cfg, cfg->native_code, code, ARMREG_LR, MONO_PATCH_INFO_NURSERY_START_SHIFTED, NULL);
+                               code = emit_aotconst (cfg, cfg->native_code, code, ARMREG_IP, MONO_PATCH_INFO_NURSERY_SHIFT, NULL);
+                               ARM_SHR_REG (code, ARMREG_IP, value, ARMREG_IP);
+                               ARM_CMP_REG_REG (code, ARMREG_LR, ARMREG_IP);
+                               br = code;
+                               ARM_B_COND (code, ARMCOND_NE, 0);
+                               //ARM_B (code, 0);
+                       }
+
+                       code = emit_aotconst (cfg, cfg->native_code, code, ARMREG_LR, MONO_PATCH_INFO_GC_CARD_TABLE_ADDR, NULL);
+                       ARM_SHR_IMM (code, ARMREG_IP, ptr, card_table_shift);
+                       if (card_table_mask) {
+                               imm8 = mono_arm_is_rotated_imm8 ((gsize)card_table_mask, &rot_amount);
+                               g_assert (imm8 >= 0);
+                               ARM_AND_REG_IMM (code, ARMREG_IP, ARMREG_IP, imm8, rot_amount);
+                       }
+                       ARM_ADD_REG_REG (code, ARMREG_LR, ARMREG_LR, ARMREG_IP);
+                       code = mono_arm_emit_load_imm (code, ARMREG_IP, 1);
+                       ARM_STRB_IMM (code, ARMREG_IP, 0, ARMREG_LR);
+
+                       arm_patch (br, code);
+                       break;
+               }
                /*case OP_BIGMUL:
                        ppc_mullw (code, ppc_r4, ins->sreg1, ins->sreg2);
                        ppc_mulhw (code, ppc_r3, ins->sreg1, ins->sreg2);
index c1f21f8995ad9b794a8bb50646965dfb5c53709e..0810b6c82fc456d8f0a83897128db213d2eea7eb 100644 (file)
@@ -254,6 +254,7 @@ typedef struct MonoCompileArch {
 #define MONO_ARCH_HAVE_GENERAL_RGCTX_LAZY_FETCH_TRAMPOLINE 1
 #define MONO_ARCH_HAVE_OPCODE_NEEDS_EMULATION 1
 #define MONO_ARCH_HAVE_OBJC_GET_SELECTOR 1
+#define MONO_ARCH_HAVE_CARD_TABLE_WBARRIER_IN_AOT 1
 
 #if defined(__native_client__)
 #undef MONO_ARCH_SOFT_DEBUG_SUPPORTED
index 534c2e20499304b2ee34e405ba8e95a110f53d12..38751953604829806ba7e24a5b89faf35989df6f 100644 (file)
@@ -3220,6 +3220,8 @@ mono_patch_info_hash (gconstpointer data)
        case MONO_PATCH_INFO_MONITOR_EXIT:
        case MONO_PATCH_INFO_CASTCLASS_CACHE:
        case MONO_PATCH_INFO_GOT_OFFSET:
+       case MONO_PATCH_INFO_NURSERY_START_SHIFTED:
+       case MONO_PATCH_INFO_NURSERY_SHIFT:
                return (ji->type << 8);
        case MONO_PATCH_INFO_SWITCH:
                return (ji->type << 8) | ji->data.table->table_size;
@@ -3669,6 +3671,23 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code,
                target = NULL;
                break;
        }
+       case MONO_PATCH_INFO_NURSERY_START_SHIFTED: {
+               size_t nursery_size;
+               int nursery_shift;
+               gpointer nursery_start = mono_gc_get_nursery (&nursery_shift, &nursery_size);
+
+               target = (gpointer)((gsize)nursery_start >> nursery_shift);
+               break;
+       }
+       case MONO_PATCH_INFO_NURSERY_SHIFT: {
+               size_t nursery_size;
+               int nursery_shift;
+
+               mono_gc_get_nursery (&nursery_shift, &nursery_size);
+
+               target = GINT_TO_POINTER (nursery_shift);
+               break;
+       }
        default:
                g_assert_not_reached ();
        }
index 12c55254231904484cd34b4a7f9625e677830486..0923394737731c81c272eefe767266c6a43f7775 100644 (file)
@@ -51,4 +51,6 @@ PATCH_INFO(JIT_TLS_ID, "jit_tls_id")
 PATCH_INFO(TLS_OFFSET, "tls_offset")
 PATCH_INFO(OBJC_SELECTOR_REF, "objc_selector_ref")
 PATCH_INFO(METHOD_CODE_SLOT, "method_code_slot")
+PATCH_INFO(NURSERY_START_SHIFTED, "nursery_start_shifted")
+PATCH_INFO(NURSERY_SHIFT, "nursery_shift")
 PATCH_INFO(NONE, "none")