* mini.c (mono_resolve_patch_target): Handle LAZY_FETCH_TRAMPOLINE.
(mono_codegen): Ditto.
* aot-compiler.c aot-runtime.c: Ditto.
* patch-info.h: Add MONO_PATCH_INFO_RGCTX_LAZY_FETCH_TRAMPOLINE.
* mini-trampolines.c (mono_find_rgctx_lazy_fetch_trampoline_by_addr): New
helper function to find the offset corresponding to a lazy fetch trampoline.
* mini.h (MonoCompile): Add 'orig_method' field to hold the original method
when doing generic sharing.
* aot-compiler.c: Use cfg->orig_method instead of cfg->method in a lot of
places.
svn path=/trunk/mono/; revision=110667
2008-08-17 Zoltan Varga <vargaz@gmail.com>
+ * mini.c (mono_resolve_patch_target): Handle LAZY_FETCH_TRAMPOLINE.
+ (mono_codegen): Ditto.
+
+ * aot-compiler.c aot-runtime.c: Ditto.
+
+ * patch-info.h: Add MONO_PATCH_INFO_RGCTX_LAZY_FETCH_TRAMPOLINE.
+
+ * mini-trampolines.c (mono_find_rgctx_lazy_fetch_trampoline_by_addr): New
+ helper function to find the offset corresponding to a lazy fetch trampoline.
+
+ * mini.h (MonoCompile): Add 'orig_method' field to hold the original method
+ when doing generic sharing.
+
+ * aot-compiler.c: Use cfg->orig_method instead of cfg->method in a lot of
+ places.
+
+ * mini.c (mono_create_rgctx_lazy_fetch_trampoline): Move this to
+ mini-trampolines.c to be with the other trampoline creation functions.
+
* method-to-ir.c (mono_emit_method_call): Remove the 'signature' argument
as it is equal to method->signature in most cases, add a
mono_emit_method_call_full variant which takes a signature and an imt
case MONO_PATCH_INFO_WRAPPER:
case MONO_PATCH_INFO_INTERNAL_METHOD:
case MONO_PATCH_INFO_JIT_ICALL_ADDR:
- case MONO_PATCH_INFO_CLASS_INIT: {
+ case MONO_PATCH_INFO_CLASS_INIT:
+ case MONO_PATCH_INFO_RGCTX_LAZY_FETCH_TRAMPOLINE: {
MonoJumpInfo *new_ji = mono_patch_info_dup_mp (acfg->mempool, patch_info);
gpointer patch_id = NULL;
case MONO_PATCH_INFO_CLASS_INIT:
patch_id = patch_info->data.klass;
break;
+ case MONO_PATCH_INFO_RGCTX_LAZY_FETCH_TRAMPOLINE:
+ patch_id = GUINT_TO_POINTER (patch_info->data.offset + 1);
+ break;
case MONO_PATCH_INFO_WRAPPER:
hash = acfg->patch_to_plt_offset_wrapper [patch_info->data.method->wrapper_type];
if (!hash) {
int func_alignment = 16;
MonoMethodHeader *header;
- method = cfg->method;
+ method = cfg->orig_method;
code = cfg->native_code;
header = mono_method_get_header (method);
case MONO_PATCH_INFO_DELEGATE_TRAMPOLINE:
encode_klass_ref (acfg, patch_info->data.klass, p, &p);
break;
+ case MONO_PATCH_INFO_RGCTX_LAZY_FETCH_TRAMPOLINE:
+ encode_value (patch_info->data.offset, p, &p);
+ break;
case MONO_PATCH_INFO_FIELD:
case MONO_PATCH_INFO_SFLDA:
if (shared) {
guint8 *p, *buf;
guint32 first_got_offset;
- method = cfg->method;
+ method = cfg->orig_method;
code = cfg->native_code;
header = mono_method_get_header (method);
MonoMethodHeader *header;
guint8 *p, *buf, *debug_info;
- method = cfg->method;
+ method = cfg->orig_method;
code = cfg->native_code;
header = mono_method_get_header (method);
method = mono_get_method (acfg->image, token, NULL);
cfg = g_hash_table_lookup (acfg->method_to_cfg, method);
- if (!cfg || !cfg->method->klass->valuetype || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL))
+ if (!cfg || !cfg->orig_method->klass->valuetype || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL))
continue;
symbol = g_strdup_printf ("unbox_trampoline_%d", i);
emit_global (acfg, symbol, TRUE);
emit_label (acfg, symbol);
- call_target = g_strdup_printf (".Lm_%x", get_method_index (acfg, cfg->method));
+ call_target = g_strdup_printf (".Lm_%x", get_method_index (acfg, cfg->orig_method));
#if defined(__x86_64__)
{
guint8 buf [32];
int this_reg;
- this_reg = mono_arch_get_this_arg_reg (mono_method_signature (cfg->method), cfg->generic_sharing_context, NULL);
+ this_reg = mono_arch_get_this_arg_reg (mono_method_signature (cfg->orig_method), cfg->generic_sharing_context, NULL);
code = buf;
amd64_alu_reg_imm (code, X86_ADD, this_reg, sizeof (MonoObject));
code = buf;
- if (MONO_TYPE_ISSTRUCT (mono_method_signature (cfg->method)->ret))
+ if (MONO_TYPE_ISSTRUCT (mono_method_signature (cfg->orig_method)->ret))
this_pos = 1;
ARM_ADD_REG_IMM8 (code, this_pos, this_pos, sizeof (MonoObject));
//acfg->opts &= ~MONO_OPT_GSHARED;
// FIXME: GSHARED is on by default
+#if 1
if (TRUE || !(acfg->opts & MONO_OPT_GSHARED)) {
if (method->is_generic || method->klass->generic_container) {
acfg->stats.genericcount ++;
return;
}
}
+#endif
if (acfg->aot_opts.full_aot)
mono_use_imt = FALSE;
acfg->cfgs [index] = cfg;
- g_hash_table_insert (acfg->method_to_cfg, cfg->method, cfg);
+ g_hash_table_insert (acfg->method_to_cfg, cfg->orig_method, cfg);
acfg->stats.ccount++;
}
for (i = 0; i < acfg->nmethods; ++i) {
MonoCompile *cfg = acfg->cfgs [i];
- if (!cfg || !cfg->method->wrapper_type)
+ if (!cfg || !cfg->orig_method->wrapper_type)
continue;
- index = get_method_index (acfg, cfg->method);
+ index = get_method_index (acfg, cfg->orig_method);
// FIXME: Optimize disk usage and lookup speed
- name = mono_method_full_name (cfg->method, TRUE);
+ name = mono_method_full_name (cfg->orig_method, TRUE);
emit_string (acfg, name);
emit_alignment (acfg, 4);
emit_int32 (acfg, index);
if (!ji->data.klass)
goto cleanup;
break;
+ case MONO_PATCH_INFO_RGCTX_LAZY_FETCH_TRAMPOLINE:
+ ji->data.offset = decode_value (p, &p);
+ break;
case MONO_PATCH_INFO_IMAGE:
ji->data.image = load_image (aot_module, decode_value (p, &p));
if (!ji->data.image)
static GHashTable *class_init_hash_addr = NULL;
static GHashTable *delegate_trampoline_hash_addr = NULL;
static GHashTable *rgctx_lazy_fetch_trampoline_hash = NULL;
+static GHashTable *rgctx_lazy_fetch_trampoline_hash_addr = NULL;
#define mono_trampolines_lock() EnterCriticalSection (&trampolines_mutex)
#define mono_trampolines_unlock() LeaveCriticalSection (&trampolines_mutex)
ptr = mono_create_ftnptr (mono_get_root_domain (), tramp);
mono_trampolines_lock ();
- if (!rgctx_lazy_fetch_trampoline_hash)
+ if (!rgctx_lazy_fetch_trampoline_hash) {
rgctx_lazy_fetch_trampoline_hash = g_hash_table_new (NULL, NULL);
+ rgctx_lazy_fetch_trampoline_hash_addr = g_hash_table_new (NULL, NULL);
+ }
g_hash_table_insert (rgctx_lazy_fetch_trampoline_hash, GUINT_TO_POINTER (offset), ptr);
+ g_assert (offset != -1);
+ g_hash_table_insert (rgctx_lazy_fetch_trampoline_hash_addr, ptr, GUINT_TO_POINTER (offset + 1));
mono_trampolines_unlock ();
if (!inited) {
mono_trampolines_unlock ();
return res;
}
+
+guint32
+mono_find_rgctx_lazy_fetch_trampoline_by_addr (gconstpointer addr)
+{
+ int offset;
+
+ mono_trampolines_lock ();
+ if (rgctx_lazy_fetch_trampoline_hash_addr) {
+ /* We store the real offset + 1 so we can detect when the lookup fails */
+ offset = GPOINTER_TO_INT (g_hash_table_lookup (rgctx_lazy_fetch_trampoline_hash_addr, addr));
+ if (offset)
+ offset -= 1;
+ else
+ offset = -1;
+ } else {
+ offset = -1;
+ }
+ mono_trampolines_unlock ();
+ return offset;
+}
case MONO_PATCH_INFO_DELEGATE_TRAMPOLINE:
target = mono_create_delegate_trampoline (patch_info->data.klass);
break;
+ case MONO_PATCH_INFO_RGCTX_LAZY_FETCH_TRAMPOLINE:
+ target = mono_create_rgctx_lazy_fetch_trampoline (patch_info->data.offset);
+ break;
case MONO_PATCH_INFO_SFLDA: {
MonoVTable *vtable = mono_class_vtable (domain, patch_info->data.field->parent);
if (klass) {
patch_info->type = MONO_PATCH_INFO_DELEGATE_TRAMPOLINE;
patch_info->data.klass = klass;
+ } else {
+ int offset = mono_find_rgctx_lazy_fetch_trampoline_by_addr (patch_info->data.target);
+ if (offset != -1) {
+ patch_info->type = MONO_PATCH_INFO_RGCTX_LAZY_FETCH_TRAMPOLINE;
+ patch_info->data.offset = offset;
+ }
}
}
}
cfg->verbose_level = mini_verbose;
cfg->compile_aot = compile_aot;
cfg->skip_visibility = method->skip_visibility;
+ cfg->orig_method = method;
if (try_generic_shared)
cfg->generic_sharing_context = (MonoGenericSharingContext*)&cfg->generic_sharing_context;
cfg->token_info_hash = g_hash_table_new (NULL, NULL);
/* Size of above array */
guint32 vreg_to_inst_len;
+
+ /*
+ * The original method to compile, differs from 'method' when doing generic
+ * sharing.
+ */
+ MonoMethod *orig_method;
} MonoCompile;
typedef enum {
MonoJitICallInfo *mono_find_jit_opcode_emulation (int opcode) MONO_INTERNAL;
void mono_print_ins_index (int i, MonoInst *ins) MONO_INTERNAL;
void mono_print_ins (MonoInst *ins) MONO_INTERNAL;
-gpointer mini_create_rgctx_lazy_fetch_trampoline (guint32 offset) MONO_INTERNAL;
gboolean mini_assembly_can_skip_verification (MonoDomain *domain, MonoMethod *method) MONO_INTERNAL;
gboolean mini_method_verify (MonoCompile *cfg, MonoMethod *method) MONO_INTERNAL;
gpointer mono_create_rgctx_lazy_fetch_trampoline (guint32 offset) MONO_INTERNAL;
MonoVTable* mono_find_class_init_trampoline_by_addr (gconstpointer addr) MONO_INTERNAL;
MonoClass* mono_find_delegate_trampoline_by_addr (gconstpointer addr) MONO_INTERNAL;
+guint32 mono_find_rgctx_lazy_fetch_trampoline_by_addr (gconstpointer addr) MONO_INTERNAL;
gpointer mono_magic_trampoline (gssize *regs, guint8 *code, MonoMethod *m, guint8* tramp) MONO_INTERNAL;
gpointer mono_delegate_trampoline (gssize *regs, guint8 *code, gpointer *tramp_data, guint8* tramp) MONO_INTERNAL;
gpointer mono_aot_trampoline (gssize *regs, guint8 *code, guint8 *token_info,
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_LAZY_FETCH_TRAMPOLINE, "rgctx_lazy_fetch_trampoline")
PATCH_INFO(NONE, "none")