#include <mono/utils/mono-threads-coop.h>
#include "mini.h"
+#include "lldb.h"
/*
* Address of the trampoline code. This is used by the debugger to check
* Either IMPL_METHOD or OUT_AOT_ADDR will be set on return.
*/
gpointer*
-mini_resolve_imt_method (MonoVTable *vt, gpointer *vtable_slot, MonoMethod *imt_method, MonoMethod **impl_method, gpointer *out_aot_addr, gboolean *out_need_rgctx_tramp, MonoMethod **variant_iface)
+mini_resolve_imt_method (MonoVTable *vt, gpointer *vtable_slot, MonoMethod *imt_method, MonoMethod **impl_method, gpointer *out_aot_addr, gboolean *out_need_rgctx_tramp, MonoMethod **variant_iface, MonoError *error)
{
MonoMethod *impl = NULL, *generic_virtual = NULL;
gboolean lookup_aot, variance_used = FALSE, need_rgctx_tramp = FALSE;
g_assert (imt_slot < MONO_IMT_SIZE);
+ mono_error_init (error);
/* This has to be variance aware since imt_method can be from an interface that vt->klass doesn't directly implement */
interface_offset = mono_class_interface_offset_with_variance (vt->klass, imt_method->klass, &variance_used);
if (interface_offset < 0)
mono_vtable_build_imt_slot (vt, mono_method_get_imt_slot (imt_method));
if (imt_method->is_inflated && ((MonoMethodInflated*)imt_method)->context.method_inst) {
- MonoError error;
MonoGenericContext context = { NULL, NULL };
/*
/* imt_method->slot might not be set */
impl = mono_class_get_vtable_entry (vt->klass, interface_offset + mono_method_get_declaring_generic_method (imt_method)->slot);
- if (impl->klass->generic_class)
- context.class_inst = impl->klass->generic_class->context.class_inst;
+ if (mono_class_is_ginst (impl->klass))
+ context.class_inst = mono_class_get_generic_class (impl->klass)->context.class_inst;
context.method_inst = ((MonoMethodInflated*)imt_method)->context.method_inst;
- impl = mono_class_inflate_generic_method_checked (impl, &context, &error);
- g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
+ impl = mono_class_inflate_generic_method_checked (impl, &context, error);
+ mono_error_assert_ok (error);
} else {
- MonoError error;
/* Avoid loading metadata or creating a generic vtable if possible */
if (lookup_aot && !vt->klass->valuetype) {
- aot_addr = (guint8 *)mono_aot_get_method_from_vt_slot (mono_domain_get (), vt, interface_offset + mono_method_get_vtable_slot (imt_method), &error);
- mono_error_raise_exception (&error); // FIXME: Don't raise here
+ aot_addr = (guint8 *)mono_aot_get_method_from_vt_slot (mono_domain_get (), vt, interface_offset + mono_method_get_vtable_slot (imt_method), error);
+ return_val_if_nok (error, NULL);
} else {
aot_addr = NULL;
}
if (callee_array_helper) {
add_static_rgctx_tramp = FALSE;
- /* FIXME: ji->from_aot is not set for llvm methods */
- if (ji && (ji->from_aot || mono_aot_only)) {
- /* In AOT mode, compiled_method points to one of the InternalArray methods in Array. */
- if (!mono_llvm_only && mono_method_needs_static_rgctx_invoke (jinfo_get_method (ji), TRUE))
- add_static_rgctx_tramp = TRUE;
- }
+ /* In AOT mode, compiled_method points to one of the InternalArray methods in Array. */
+ if (ji && !mono_llvm_only && mono_method_needs_static_rgctx_invoke (jinfo_get_method (ji), TRUE))
+ add_static_rgctx_tramp = TRUE;
}
if (mono_llvm_only)
need_rgctx_tramp = TRUE;
}
- vtable_slot = mini_resolve_imt_method (vt, vtable_slot, imt_method, &impl_method, &addr, &need_rgctx_tramp, &variant_iface);
- /* This is the vcall slot which gets called through the IMT thunk */
+ vtable_slot = mini_resolve_imt_method (vt, vtable_slot, imt_method, &impl_method, &addr, &need_rgctx_tramp, &variant_iface, error);
+ return_val_if_nok (error, NULL);
+
+ /* This is the vcall slot which gets called through the IMT trampoline */
vtable_slot_to_patch = vtable_slot;
if (addr) {
* return TRUE for methods used in IMT calls too.
*/
if (virtual_ && is_generic_method_definition (m)) {
- MonoError error;
MonoGenericContext context = { NULL, NULL };
MonoMethod *declaring;
else
declaring = m;
- if (m->klass->generic_class)
- context.class_inst = m->klass->generic_class->context.class_inst;
+ if (mono_class_is_ginst (m->klass))
+ context.class_inst = mono_class_get_generic_class (m->klass)->context.class_inst;
else
- g_assert (!m->klass->generic_container);
+ g_assert (!mono_class_is_gtd (m->klass));
generic_virtual = mono_arch_find_imt_method (regs, code);
g_assert (generic_virtual);
g_assert (generic_virtual->is_inflated);
context.method_inst = ((MonoMethodInflated*)generic_virtual)->context.method_inst;
- m = mono_class_inflate_generic_method_checked (declaring, &context, &error);
- g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
+ m = mono_class_inflate_generic_method_checked (declaring, &context, error);
+ mono_error_assert_ok (error);
/* FIXME: only do this if the method is sharable */
need_rgctx_tramp = TRUE;
} else if ((context_used = mono_method_check_context_used (m))) {
}
if (method_inst || m->wrapper_type) {
- MonoError error;
MonoGenericContext context = { NULL, NULL };
if (m->is_inflated)
else
declaring = m;
- if (klass->generic_class)
- context.class_inst = klass->generic_class->context.class_inst;
- else if (klass->generic_container)
- context.class_inst = klass->generic_container->context.class_inst;
+ if (mono_class_is_ginst (klass))
+ context.class_inst = mono_class_get_generic_class (klass)->context.class_inst;
+ else if (mono_class_is_gtd (klass))
+ context.class_inst = mono_class_get_generic_container (klass)->context.class_inst;
context.method_inst = method_inst;
- actual_method = mono_class_inflate_generic_method_checked (declaring, &context, &error);
- g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
+ actual_method = mono_class_inflate_generic_method_checked (declaring, &context, error);
+ mono_error_assert_ok (error);
} else {
actual_method = mono_class_get_method_generic (klass, m);
}
*/
no_patch = TRUE;
}
-
+#if LLVM_API_VERSION > 100
+ /* LLVM code doesn't make direct calls */
+ if (ji && ji->from_llvm)
+ no_patch = TRUE;
+#endif
if (!no_patch && mono_method_same_domain (ji, target_ji))
mono_arch_patch_callsite ((guint8 *)ji->code_start, code, (guint8 *)addr);
}
gpointer *vtable_slot;
MonoMethod *m;
MonoError error;
- gpointer addr, res;
+ gpointer addr, res = NULL;
trampoline_calls ++;
else
declaring = m;
- if (m->klass->generic_class)
- context.class_inst = m->klass->generic_class->context.class_inst;
+ if (mono_class_is_ginst (m->klass))
+ context.class_inst = mono_class_get_generic_class (m->klass)->context.class_inst;
else
- g_assert (!m->klass->generic_container);
+ g_assert (!mono_class_is_gtd (m->klass));
imt_method = mono_arch_find_imt_method (regs, code);
if (imt_method->is_inflated)
* If the call doesn't return a valuetype, then the vcall uses the same calling
* convention as a normal call.
*/
- if (((method->klass->flags & TYPE_ATTRIBUTE_SEALED) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)) && !MONO_TYPE_ISSTRUCT (sig->ret)) {
+ if ((mono_class_is_sealed (method->klass) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)) && !MONO_TYPE_ISSTRUCT (sig->ret)) {
callvirt = FALSE;
enable_caching = FALSE;
}
if (delegate->target &&
method->flags & METHOD_ATTRIBUTE_VIRTUAL &&
method->flags & METHOD_ATTRIBUTE_ABSTRACT &&
- method->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) {
+ mono_class_is_abstract (method->klass)) {
method = mono_object_get_virtual_method (delegate->target, method);
enable_caching = FALSE;
}
MonoContext ctx;
MonoException *exc;
- MonoJitTlsData *jit_tls = (MonoJitTlsData *)mono_native_tls_get_value (mono_jit_tls_id);
+ MonoJitTlsData *jit_tls = (MonoJitTlsData *)mono_tls_get_jit_tls ();
gpointer resume_ip = jit_tls->handler_block_return_address;
memcpy (&ctx, &jit_tls->handler_block_context, sizeof (MonoContext));
mono_create_handler_block_trampoline (void)
{
static gpointer code;
- if (code) {
+
+ if (code)
+ return code;
+
+ if (mono_aot_only) {
+ gpointer tmp = mono_aot_get_trampoline ("handler_block_trampoline");
+ g_assert (tmp);
mono_memory_barrier ();
+ code = tmp;
return code;
}
- g_assert (!mono_aot_only);
-
mono_trampolines_lock ();
-
if (!code) {
MonoTrampInfo *info;
gpointer tmp;
gpointer
mono_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len)
{
+ gpointer code;
+ guint32 len;
+
if (mono_aot_only)
- return mono_aot_create_specific_trampoline (mono_defaults.corlib, arg1, tramp_type, domain, code_len);
+ code = mono_aot_create_specific_trampoline (mono_defaults.corlib, arg1, tramp_type, domain, &len);
else
- return mono_arch_create_specific_trampoline (arg1, tramp_type, domain, code_len);
+ code = mono_arch_create_specific_trampoline (arg1, tramp_type, domain, &len);
+ mono_lldb_save_specific_trampoline_info (arg1, tramp_type, domain, code, len);
+ if (code_len)
+ *code_len = len;
+ return code;
}
gpointer
mono_error_init (error);
if (mono_aot_only) {
+ if (mono_llvm_only && method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
+ method = mono_marshal_get_synchronized_wrapper (method);
+
/* Avoid creating trampolines if possible */
gpointer code = mono_jit_find_compiled_method (domain, method);
if (code)
return code;
if (mono_llvm_only) {
- if (method->wrapper_type == MONO_WRAPPER_PROXY_ISINST || method->wrapper_type == MONO_WRAPPER_LDFLD_REMOTE ||
- method->wrapper_type == MONO_WRAPPER_STFLD_REMOTE)
+ if (method->wrapper_type == MONO_WRAPPER_PROXY_ISINST)
/* These wrappers are not generated */
return method_not_found;
/* Methods are lazily initialized on first call, so this can't lead recursion */