Implement rgctx fetches by calling a JIT icall.
authorZoltan Varga <vargaz@gmail.com>
Wed, 8 Jul 2015 00:35:59 +0000 (20:35 -0400)
committerZoltan Varga <vargaz@gmail.com>
Fri, 9 Oct 2015 02:41:28 +0000 (22:41 -0400)
mono/mini/aot-compiler.c
mono/mini/aot-runtime.c
mono/mini/method-to-ir.c
mono/mini/mini-runtime.c
mono/mini/patch-info.h

index 982dda443059b7ff3317dd9e04da662eaed69d60..3ff176337bdc217eac4d71646263b9ab5134279e 100644 (file)
@@ -5280,7 +5280,8 @@ encode_patch (MonoAotCompile *acfg, MonoJumpInfo *patch_info, guint8 *buf, guint
                break;
        case MONO_PATCH_INFO_INTERRUPTION_REQUEST_FLAG:
                break;
-       case MONO_PATCH_INFO_RGCTX_FETCH: {
+       case MONO_PATCH_INFO_RGCTX_FETCH:
+       case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
                MonoJumpInfoRgctxEntry *entry = patch_info->data.rgctx_entry;
                guint32 offset;
                guint8 *buf2, *p2;
@@ -6793,7 +6794,8 @@ can_encode_patch (MonoAotCompile *acfg, MonoJumpInfo *patch_info)
                }
                break;
        }
-       case MONO_PATCH_INFO_RGCTX_FETCH: {
+       case MONO_PATCH_INFO_RGCTX_FETCH:
+       case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
                MonoJumpInfoRgctxEntry *entry = patch_info->data.rgctx_entry;
 
                if (!can_encode_method (acfg, entry->method))
@@ -6985,10 +6987,11 @@ compile_method (MonoAotCompile *acfg, MonoMethod *method)
                for (patch_info = cfg->patch_info; patch_info; patch_info = patch_info->next) {
                        switch (patch_info->type) {
                        case MONO_PATCH_INFO_RGCTX_FETCH:
+                       case MONO_PATCH_INFO_RGCTX_SLOT_INDEX:
                        case MONO_PATCH_INFO_METHOD: {
                                MonoMethod *m = NULL;
 
-                               if (patch_info->type == MONO_PATCH_INFO_RGCTX_FETCH) {
+                               if (patch_info->type == MONO_PATCH_INFO_RGCTX_FETCH || patch_info->type == MONO_PATCH_INFO_RGCTX_SLOT_INDEX) {
                                        MonoJumpInfoRgctxEntry *e = patch_info->data.rgctx_entry;
 
                                        if (e->info_type == MONO_RGCTX_INFO_GENERIC_METHOD_CODE)
index 13fa760881b21e2f10c1407c019223ceda16c790..a0bebe4b2da88921a50ce41fe53c8bafae233e9a 100644 (file)
@@ -3386,7 +3386,8 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin
        case MONO_PATCH_INFO_CASTCLASS_CACHE:
                ji->data.index = decode_value (p, &p);
                break;
-       case MONO_PATCH_INFO_RGCTX_FETCH: {
+       case MONO_PATCH_INFO_RGCTX_FETCH:
+       case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
                gboolean res;
                MonoJumpInfoRgctxEntry *entry;
                guint32 offset, val;
index 785b5f8f21b3b4f5c7b8ffae79ecef128339b330..f8fc77cdf79a3c8850853f8d98efbee27b634d26 100644 (file)
@@ -3420,18 +3420,26 @@ mono_patch_info_rgctx_entry_new (MonoMemPool *mp, MonoMethod *method, gboolean i
        return res;
 }
 
-/*
- * emit_rgctx_fetch:
- *
- *   Emit IR to load the value of the rgctx entry ENTRY from the rgctx
- * given by RGCTX.
- */
 static inline MonoInst*
-emit_rgctx_fetch (MonoCompile *cfg, MonoInst *rgctx, MonoJumpInfoRgctxEntry *entry)
+emit_rgctx_fetch_inline (MonoCompile *cfg, MonoInst *rgctx, MonoJumpInfoRgctxEntry *entry)
 {
-       /* Inline version, not currently used */
-       // FIXME: This can be called from mono_decompose_vtype_opts (), which can't create new bblocks
+       MonoInst *args [16];
+       MonoInst *call;
+
+       // FIXME: No fastpath since the slot is not a compile time constant
+       args [0] = rgctx;
+       EMIT_NEW_AOTCONST (cfg, args [1], MONO_PATCH_INFO_RGCTX_SLOT_INDEX, entry);
+       if (entry->in_mrgctx)
+               call = mono_emit_jit_icall (cfg, mono_fill_method_rgctx, args);
+       else
+               call = mono_emit_jit_icall (cfg, mono_fill_class_rgctx, args);
+       return call;
 #if 0
+       /*
+        * FIXME: This can be called during decompose, which is a problem since it creates
+        * new bblocks.
+        * Also, the fastpath doesn't work since the slot number is dynamically allocated.
+        */
        int i, slot, depth, index, rgctx_reg, val_reg, res_reg;
        gboolean mrgctx;
        MonoBasicBlock *is_null_bb, *end_bb;
@@ -3517,11 +3525,24 @@ emit_rgctx_fetch (MonoCompile *cfg, MonoInst *rgctx, MonoJumpInfoRgctxEntry *ent
        MONO_START_BB (cfg, end_bb);
 
        return res;
-#else
-       return mono_emit_abs_call (cfg, MONO_PATCH_INFO_RGCTX_FETCH, entry, helper_sig_rgctx_lazy_fetch_trampoline, &rgctx);
 #endif
 }
 
+/*
+ * emit_rgctx_fetch:
+ *
+ *   Emit IR to load the value of the rgctx entry ENTRY from the rgctx
+ * given by RGCTX.
+ */
+static inline MonoInst*
+emit_rgctx_fetch (MonoCompile *cfg, MonoInst *rgctx, MonoJumpInfoRgctxEntry *entry)
+{
+       if (cfg->flags & JIT_FLAG_LLVM_ONLY)
+               return emit_rgctx_fetch_inline (cfg, rgctx, entry);
+       else
+               return mono_emit_abs_call (cfg, MONO_PATCH_INFO_RGCTX_FETCH, entry, helper_sig_rgctx_lazy_fetch_trampoline, &rgctx);
+}
+
 static MonoInst*
 emit_get_rgctx_klass (MonoCompile *cfg, int context_used,
                                          MonoClass *klass, MonoRgctxInfoType rgctx_type)
index b56e0c1ad5b6a07ebc1a1842779706af1699dafc..2a53bf6af3aaefd8df1a35b92946e78a2b55451c 100644 (file)
@@ -1121,6 +1121,7 @@ mono_patch_info_dup_mp (MonoMemPool *mp, MonoJumpInfo *patch_info)
                memcpy (res->data.table->table, patch_info->data.table->table, sizeof (MonoBasicBlock*) * patch_info->data.table->table_size);
                break;
        case MONO_PATCH_INFO_RGCTX_FETCH:
+       case MONO_PATCH_INFO_RGCTX_SLOT_INDEX:
                res->data.rgctx_entry = mono_mempool_alloc (mp, sizeof (MonoJumpInfoRgctxEntry));
                memcpy (res->data.rgctx_entry, patch_info->data.rgctx_entry, sizeof (MonoJumpInfoRgctxEntry));
                res->data.rgctx_entry->data = mono_patch_info_dup_mp (mp, res->data.rgctx_entry->data);
@@ -1204,7 +1205,8 @@ mono_patch_info_hash (gconstpointer data)
                return (ji->type << 8) | (gssize)ji->data.target;
        case MONO_PATCH_INFO_GSHAREDVT_CALL:
                return (ji->type << 8) | (gssize)ji->data.gsharedvt->method;
-       case MONO_PATCH_INFO_RGCTX_FETCH: {
+       case MONO_PATCH_INFO_RGCTX_FETCH:
+       case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
                MonoJumpInfoRgctxEntry *e = ji->data.rgctx_entry;
 
                return (ji->type << 8) | (gssize)e->method | (e->in_mrgctx) | e->info_type | mono_patch_info_hash (e->data);
@@ -1277,7 +1279,8 @@ mono_patch_info_equal (gconstpointer ka, gconstpointer kb)
                break;
        case MONO_PATCH_INFO_INTERNAL_METHOD:
                return g_str_equal (ji1->data.name, ji2->data.name);
-       case MONO_PATCH_INFO_RGCTX_FETCH: {
+       case MONO_PATCH_INFO_RGCTX_FETCH:
+       case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
                MonoJumpInfoRgctxEntry *e1 = ji1->data.rgctx_entry;
                MonoJumpInfoRgctxEntry *e2 = ji2->data.rgctx_entry;
 
@@ -1592,6 +1595,12 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code,
                target = mono_method_lookup_rgctx (vtable, mini_method_get_context (patch_info->data.method)->method_inst);
                break;
        }
+       case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
+               int slot = mini_get_rgctx_entry_slot (patch_info->data.rgctx_entry);
+
+               target = GINT_TO_POINTER (MONO_RGCTX_SLOT_INDEX (slot));
+               break;
+       }
        case MONO_PATCH_INFO_BB_OVF:
        case MONO_PATCH_INFO_EXC_OVF:
        case MONO_PATCH_INFO_GOT_OFFSET:
index 8a74146c1c494abdacb178160f935f2cb9086c3c..47cef5724e1222a1a599f8e1274cd072766ac941 100644 (file)
@@ -35,6 +35,7 @@ PATCH_INFO(JIT_ICALL_ADDR, "jit_icall_addr")
 PATCH_INFO(INTERRUPTION_REQUEST_FLAG, "interruption_request_flag")
 PATCH_INFO(METHOD_RGCTX, "method_rgctx")
 PATCH_INFO(RGCTX_FETCH, "rgctx_fetch")
+PATCH_INFO(RGCTX_SLOT_INDEX, "rgctx_slot_index")
 PATCH_INFO(MONITOR_ENTER, "monitor_enter")
 PATCH_INFO(MONITOR_ENTER_V4, "monitor_enter_v4")
 PATCH_INFO(MONITOR_EXIT, "monitor_exit")