g_assert_not_reached ();
break;
case MONO_WRAPPER_STATIC_RGCTX_INVOKE:
- case MONO_WRAPPER_SYNCHRONIZED: {
+ case MONO_WRAPPER_SYNCHRONIZED:
+ case MONO_WRAPPER_MANAGED_TO_NATIVE: {
MonoMethod *m;
m = mono_marshal_method_from_wrapper (method);
g_assert (m);
+ g_assert (m != method);
encode_method_ref (acfg, m, p, &p);
break;
}
return hash;
}
+/*
+ * mono_aot_wrapper_name:
+ *
+ * Return a string which uniqely identifies the given wrapper method.
+ */
+char*
+mono_aot_wrapper_name (MonoMethod *method)
+{
+ char *name, *tmpsig, *klass_desc;
+
+ tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
+
+ switch (method->wrapper_type) {
+ case MONO_WRAPPER_RUNTIME_INVOKE:
+ case MONO_WRAPPER_DELEGATE_INVOKE:
+ case MONO_WRAPPER_DELEGATE_BEGIN_INVOKE:
+ case MONO_WRAPPER_DELEGATE_END_INVOKE:
+ /* This is a hack to work around the fact that runtime invoke wrappers get assigned to some random class */
+ name = g_strdup_printf ("%s (%s)", method->name, tmpsig);
+ break;
+ default:
+ klass_desc = mono_type_full_name (&method->klass->byval_arg);
+
+ name = g_strdup_printf ("%s:%s (%s)", klass_desc, method->name, tmpsig);
+ break;
+ }
+
+ g_free (tmpsig);
+
+ return name;
+}
+
#if !defined(DISABLE_AOT) && !defined(DISABLE_JIT)
typedef struct HashEntry {
for (i = 0; i < acfg->extra_methods->len; ++i) {
MonoMethod *method = g_ptr_array_index (acfg->extra_methods, i);
MonoCompile *cfg = g_hash_table_lookup (acfg->method_to_cfg, method);
+ char *name;
if (!cfg)
continue;
nmethods ++;
info_offsets [i] = p - buf;
+ name = NULL;
if (method->wrapper_type) {
- char *name;
-
- // FIXME: Optimize disk usage
- if (method->wrapper_type == MONO_WRAPPER_RUNTIME_INVOKE) {
- char *tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
- name = g_strdup_printf ("(wrapper runtime-invoke):%s (%s)", method->name, tmpsig);
- g_free (tmpsig);
- } else if (method->wrapper_type == MONO_WRAPPER_DELEGATE_INVOKE) {
- char *tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
- name = g_strdup_printf ("(wrapper delegate-invoke):%s (%s)", method->name, tmpsig);
- g_free (tmpsig);
- } else if (method->wrapper_type == MONO_WRAPPER_DELEGATE_BEGIN_INVOKE) {
- char *tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
- name = g_strdup_printf ("(wrapper delegate-begin-invoke):%s (%s)", method->name, tmpsig);
- g_free (tmpsig);
- } else if (method->wrapper_type == MONO_WRAPPER_DELEGATE_END_INVOKE) {
- char *tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
- name = g_strdup_printf ("(wrapper delegate-end-invoke):%s (%s)", method->name, tmpsig);
- g_free (tmpsig);
- } else {
- name = mono_method_full_name (cfg->orig_method, TRUE);
+ /*
+ * We encode some wrappers using their name, since encoding them
+ * directly would be difficult. This also avoids creating the wrapper
+ * methods at runtime, since they are not needed anyway.
+ */
+ switch (method->wrapper_type) {
+ case MONO_WRAPPER_REMOTING_INVOKE_WITH_CHECK:
+ case MONO_WRAPPER_SYNCHRONIZED:
+ /* encode_method_ref () can handle these */
+ break;
+ default:
+ name = mono_aot_wrapper_name (method);
+ break;
}
+ }
+ if (name) {
encode_value (1, p, &p);
+ encode_value (method->wrapper_type, p, &p);
strcpy ((char*)p, name);
p += strlen (name ) + 1;
g_free (name);
{
guint32 table_size, entry_size, hash;
guint32 *table, *entry;
- char *full_name = NULL;
+ char *name = NULL;
int num_checks = 0;
+ guint32 index;
if (!amodule)
return 0xffffff;
entry_size = 3;
if (method->wrapper_type) {
- /* FIXME: This is a hack to work around the fact that runtime invoke wrappers get assigned to some random class */
- if (method->wrapper_type == MONO_WRAPPER_RUNTIME_INVOKE) {
- char *tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
- full_name = g_strdup_printf ("(wrapper runtime-invoke):%s (%s)", method->name, tmpsig);
- g_free (tmpsig);
- } else if (method->wrapper_type == MONO_WRAPPER_DELEGATE_INVOKE) {
- char *tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
- full_name = g_strdup_printf ("(wrapper delegate-invoke):%s (%s)", method->name, tmpsig);
- g_free (tmpsig);
- } else if (method->wrapper_type == MONO_WRAPPER_DELEGATE_BEGIN_INVOKE) {
- char *tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
- full_name = g_strdup_printf ("(wrapper delegate-begin-invoke):%s (%s)", method->name, tmpsig);
- g_free (tmpsig);
- } else if (method->wrapper_type == MONO_WRAPPER_DELEGATE_END_INVOKE) {
- char *tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
- full_name = g_strdup_printf ("(wrapper delegate-end-invoke):%s (%s)", method->name, tmpsig);
- g_free (tmpsig);
- } else {
- full_name = mono_method_full_name (method, TRUE);
- }
+ name = mono_aot_wrapper_name (method);
}
hash = mono_aot_method_hash (method) % table_size;
if (entry [0] == 0)
return 0xffffff;
+ index = 0xffffff;
while (TRUE) {
guint32 key = entry [0];
guint32 value = entry [1];
guint32 next = entry [entry_size - 1];
MonoMethod *m;
guint8 *p;
- int is_wrapper;
+ int is_wrapper_name;
p = amodule->extra_method_info + key;
- is_wrapper = decode_value (p, &p);
- if (is_wrapper) {
- if (full_name && !strcmp (full_name, (char*)p))
- return value;
+ is_wrapper_name = decode_value (p, &p);
+ if (is_wrapper_name) {
+ int wrapper_type = decode_value (p, &p);
+ if (wrapper_type == method->wrapper_type && !strcmp (name, (char*)p)) {
+ index = value;
+ break;
+ }
} else if (can_method_ref_match_method (amodule, p, method)) {
num_checks ++;
mono_aot_lock ();
if (m)
printf ("%d %s %s\n", num_checks, mono_method_full_name (method, TRUE), mono_method_full_name (m, TRUE));
*/
- if (m == method)
- return value;
+ if (m == method) {
+ index = value;
+ break;
+ }
}
if (next != 0)
break;
}
- return 0xffffff;
+ g_free (name);
+ return index;
}
static void
#define MONO_FAKE_VTABLE_METHOD ((MonoMethod*)GINT_TO_POINTER(-2))
/* Version number of the AOT file format */
-#define MONO_AOT_FILE_VERSION "48"
+#define MONO_AOT_FILE_VERSION "49"
/* Constants used to encode different types of methods in AOT */
enum {
gpointer mono_aot_get_lazy_fetch_trampoline (guint32 slot) MONO_INTERNAL;
guint8* mono_aot_get_unwind_info (MonoJitInfo *ji, guint32 *unwind_info_len) MONO_INTERNAL;
guint32 mono_aot_method_hash (MonoMethod *method) MONO_INTERNAL;
+char* mono_aot_wrapper_name (MonoMethod *method) MONO_INTERNAL;
/* This is an exported function */
void mono_aot_register_globals (gpointer *globals);
/* This too */