Example #1
0
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);
	}
}
Example #2
0
/*
 * 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;
}