static gpointer get_unbox_trampoline (MonoMethod *m, gpointer addr, gboolean need_rgctx_tramp) { if (mono_aot_only) { if (need_rgctx_tramp) /* * The unbox trampolines call the method directly, so need to add * an rgctx tramp before them. */ return mono_create_static_rgctx_trampoline (m, mono_aot_get_unbox_trampoline (m)); else return mono_aot_get_unbox_trampoline (m); } else { unbox_trampolines ++; return mono_arch_get_unbox_trampoline (m, addr); } }
/* * mini_add_method_trampoline: * * Add static rgctx/gsharedvt_in/unbox trampolines to M/COMPILED_METHOD if needed. Return the trampoline address, or * COMPILED_METHOD if no trampoline is needed. * ORIG_METHOD is the method the caller originally called i.e. an iface method, or NULL. */ gpointer mini_add_method_trampoline (MonoMethod *orig_method, MonoMethod *m, gpointer compiled_method, gboolean add_static_rgctx_tramp, gboolean add_unbox_tramp) { gpointer addr = compiled_method; gboolean callee_gsharedvt, callee_array_helper; MonoJitInfo *ji = mini_jit_info_table_find (mono_domain_get (), mono_get_addr_from_ftnptr (compiled_method), NULL); // FIXME: This loads information from AOT callee_gsharedvt = mini_jit_info_is_gsharedvt (ji); callee_array_helper = FALSE; if (m->wrapper_type == MONO_WRAPPER_MANAGED_TO_MANAGED) { WrapperInfo *info = mono_marshal_get_wrapper_info (m); /* * generic array helpers. * Have to replace the wrappers with the original generic instances. */ if (info && info->subtype == WRAPPER_SUBTYPE_GENERIC_ARRAY_HELPER) { callee_array_helper = TRUE; m = info->d.generic_array_helper.method; } } else if (m->wrapper_type == MONO_WRAPPER_UNKNOWN) { WrapperInfo *info = mono_marshal_get_wrapper_info (m); /* Same for synchronized inner wrappers */ if (info && info->subtype == WRAPPER_SUBTYPE_SYNCHRONIZED_INNER) { m = info->d.synchronized_inner.method; } } if (!orig_method) orig_method = m; if (callee_gsharedvt) g_assert (m->is_inflated); addr = compiled_method; if (add_unbox_tramp) { /* * The unbox trampolines call the method directly, so need to add * an rgctx tramp before them. */ if (mono_aot_only) { addr = mono_aot_get_unbox_trampoline (m); } else { unbox_trampolines ++; addr = mono_arch_get_unbox_trampoline (m, addr); } } if (callee_gsharedvt && mini_is_gsharedvt_variable_signature (mono_method_signature (ji->method))) { MonoGenericSharingContext *gsctx; MonoMethodSignature *sig, *gsig; /* Here m is a generic instance, while ji->method is the gsharedvt method implementing it */ /* Call from normal/gshared code to gsharedvt code with variable signature */ gsctx = mono_jit_info_get_generic_sharing_context (ji); sig = mono_method_signature (m); gsig = mono_method_signature (ji->method); addr = mini_get_gsharedvt_wrapper (TRUE, addr, sig, gsig, gsctx, -1, FALSE); //printf ("IN: %s\n", mono_method_full_name (m, TRUE)); } if (add_static_rgctx_tramp && !callee_array_helper) addr = mono_create_static_rgctx_trampoline (m, addr); return addr; }