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;
}
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))
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)
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;
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;
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)
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);
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);
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;
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:
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")