X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=mono%2Fmini%2Fmini-trampolines.c;h=7506b5ce80794164011318f39c951e60605844dd;hb=fb5bc8d4c539fe82b36f1cd3a3bc89236b39c4aa;hp=68b5a8b0a47b5efbfa8421bb212c0f8d014e905a;hpb=883a0ae745bf33b35d44bb730d5714936a2141f7;p=mono.git diff --git a/mono/mini/mini-trampolines.c b/mono/mini/mini-trampolines.c index 68b5a8b0a47..7506b5ce807 100644 --- a/mono/mini/mini-trampolines.c +++ b/mono/mini/mini-trampolines.c @@ -18,6 +18,7 @@ #include #include "mini.h" +#include "lldb.h" /* * Address of the trampoline code. This is used by the debugger to check @@ -154,7 +155,7 @@ mono_create_static_rgctx_trampoline (MonoMethod *m, gpointer addr) * 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; @@ -166,6 +167,7 @@ mini_resolve_imt_method (MonoVTable *vt, gpointer *vtable_slot, MonoMethod *imt_ 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) @@ -188,7 +190,6 @@ mini_resolve_imt_method (MonoVTable *vt, gpointer *vtable_slot, MonoMethod *imt_ 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 }; /* @@ -198,18 +199,17 @@ mini_resolve_imt_method (MonoVTable *vt, gpointer *vtable_slot, MonoMethod *imt_ /* 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; } @@ -367,12 +367,9 @@ mini_add_method_trampoline (MonoMethod *m, gpointer compiled_method, gboolean ad 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) @@ -562,8 +559,10 @@ common_call_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVTable * 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) { @@ -585,7 +584,6 @@ common_call_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVTable * * return TRUE for methods used in IMT calls too. */ if (virtual_ && is_generic_method_definition (m)) { - MonoError error; MonoGenericContext context = { NULL, NULL }; MonoMethod *declaring; @@ -594,18 +592,18 @@ common_call_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVTable * 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))) { @@ -658,7 +656,6 @@ common_call_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVTable * } if (method_inst || m->wrapper_type) { - MonoError error; MonoGenericContext context = { NULL, NULL }; if (m->is_inflated) @@ -666,14 +663,14 @@ common_call_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVTable * 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); } @@ -800,7 +797,11 @@ common_call_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVTable * */ 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); } @@ -850,7 +851,7 @@ mono_vcall_trampoline (mgreg_t *regs, guint8 *code, int slot, guint8 *tramp) gpointer *vtable_slot; MonoMethod *m; MonoError error; - gpointer addr, res; + gpointer addr, res = NULL; trampoline_calls ++; @@ -935,10 +936,10 @@ mono_generic_virtual_remoting_trampoline (mgreg_t *regs, guint8 *code, MonoMetho 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) @@ -1120,7 +1121,7 @@ mono_delegate_trampoline (mgreg_t *regs, guint8 *code, gpointer *arg, guint8* tr * delegate->method). */ #ifndef DISABLE_REMOTING - if (delegate->target && delegate->target->vtable->klass == mono_defaults.transparent_proxy_class) { + if (delegate->target && mono_object_is_transparent_proxy (delegate->target)) { is_remote = TRUE; #ifndef DISABLE_COM if (((MonoTransparentProxy *)delegate->target)->remote_class->proxy_class != mono_class_get_com_object_class () && @@ -1188,7 +1189,7 @@ mono_delegate_trampoline (mgreg_t *regs, guint8 *code, gpointer *arg, guint8* tr * 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; } @@ -1197,7 +1198,7 @@ mono_delegate_trampoline (mgreg_t *regs, guint8 *code, gpointer *arg, guint8* tr 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; } @@ -1275,7 +1276,7 @@ mono_handler_block_guard_trampoline (mgreg_t *regs, guint8 *code, gpointer *tram 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)); @@ -1301,15 +1302,19 @@ gpointer 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; @@ -1432,10 +1437,17 @@ mono_get_trampoline_code (MonoTrampolineType tramp_type) 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 @@ -1506,14 +1518,16 @@ mono_create_jit_trampoline (MonoDomain *domain, MonoMethod *method, MonoError *e 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 */