static GHashTable *rgctx_lazy_fetch_trampoline_hash_addr;
static guint32 trampoline_calls, jit_trampolines, unbox_trampolines, static_rgctx_trampolines;
-#define mono_trampolines_lock() mono_mutex_lock (&trampolines_mutex)
-#define mono_trampolines_unlock() mono_mutex_unlock (&trampolines_mutex)
+#define mono_trampolines_lock() mono_os_mutex_lock (&trampolines_mutex)
+#define mono_trampolines_unlock() mono_os_mutex_unlock (&trampolines_mutex)
static mono_mutex_t trampolines_mutex;
#ifdef MONO_ARCH_GSHARED_SUPPORTED
static gint
rgctx_tramp_info_equal (gconstpointer ka, gconstpointer kb)
{
- const RgctxTrampInfo *i1 = ka;
- const RgctxTrampInfo *i2 = kb;
+ const RgctxTrampInfo *i1 = (const RgctxTrampInfo *)ka;
+ const RgctxTrampInfo *i2 = (const RgctxTrampInfo *)kb;
if (i1->m == i2->m && i1->addr == i2->addr)
return 1;
static guint
rgctx_tramp_info_hash (gconstpointer data)
{
- const RgctxTrampInfo *info = data;
+ const RgctxTrampInfo *info = (const RgctxTrampInfo *)data;
return GPOINTER_TO_UINT (info->m) ^ GPOINTER_TO_UINT (info->addr);
}
if (mono_aot_only)
res = mono_aot_get_static_rgctx_trampoline (ctx, addr);
else
- res = mono_arch_get_static_rgctx_trampoline (m, ctx, addr);
+ res = mono_arch_get_static_rgctx_trampoline (m, (MonoMethodRuntimeGenericContext *)ctx, addr);
mono_domain_lock (domain);
/* Duplicates inserted while we didn't hold the lock are OK */
- info = mono_domain_alloc (domain, sizeof (RgctxTrampInfo));
+ info = (RgctxTrampInfo *)mono_domain_alloc (domain, sizeof (RgctxTrampInfo));
info->m = m;
info->addr = addr;
g_hash_table_insert (domain_jit_info (domain)->static_rgctx_trampoline_hash, info, res);
/* 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)
- g_error ("%s doesn't implement interface %s\n", mono_type_get_name_full (&vt->klass->byval_arg, 0), mono_type_get_name_full (&imt_method->klass->byval_arg, 0));
+ g_error ("%s doesn't implement interface %s\n", mono_type_get_name_full (&vt->klass->byval_arg, MONO_TYPE_NAME_FORMAT_IL), mono_type_get_name_full (&imt_method->klass->byval_arg, MONO_TYPE_NAME_FORMAT_IL));
*variant_iface = NULL;
if (imt_method->is_inflated && ((MonoMethodInflated*)imt_method)->context.method_inst) {
/* We can only use the AOT compiled code if we don't require further processing */
lookup_aot = !generic_virtual & !variant_iface;
- mono_vtable_build_imt_slot (vt, mono_method_get_imt_slot (imt_method));
+ if (!mono_llvm_only)
+ 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;
} else {
/* Avoid loading metadata or creating a generic vtable if possible */
if (lookup_aot && !vt->klass->valuetype)
- aot_addr = mono_aot_get_method_from_vt_slot (mono_domain_get (), vt, interface_offset + mono_method_get_vtable_slot (imt_method));
+ aot_addr = (guint8 *)mono_aot_get_method_from_vt_slot (mono_domain_get (), vt, interface_offset + mono_method_get_vtable_slot (imt_method));
else
aot_addr = NULL;
if (aot_addr)
MonoJitInfo *ji;
// FIXME: This loads information from AOT (perf problem)
- ji = mini_jit_info_table_find (mono_domain_get (), mono_get_addr_from_ftnptr (compiled_method), NULL);
+ ji = mini_jit_info_table_find (mono_domain_get (), (char *)mono_get_addr_from_ftnptr (compiled_method), NULL);
callee_gsharedvt = mini_jit_info_is_gsharedvt (ji);
callee_array_helper = FALSE;
addr = compiled_method;
if (add_unbox_tramp) {
- /*
+ /*
* The unbox trampolines call the method directly, so need to add
* an rgctx tramp before them.
*/
addr = mini_get_gsharedvt_wrapper (TRUE, addr, sig, gsig, -1, FALSE);
+ if (mono_llvm_only)
+ g_assert_not_reached ();
//printf ("IN: %s\n", mono_method_full_name (m, TRUE));
}
return addr;
}
+/*
+ * mini_create_llvmonly_ftndesc:
+ *
+ * Create a function descriptor of the form <addr, arg>, which
+ * represents a callee ADDR with ARG as the last argument.
+ * This is used for:
+ * - generic sharing (ARG is the rgctx)
+ * - gsharedvt signature wrappers (ARG is a function descriptor)
+ */
+MonoFtnDesc*
+mini_create_llvmonly_ftndesc (MonoDomain *domain, gpointer addr, gpointer arg)
+{
+ MonoFtnDesc *ftndesc = (MonoFtnDesc*)mono_domain_alloc0 (mono_domain_get (), 2 * sizeof (gpointer));
+ ftndesc->addr = addr;
+ ftndesc->arg = arg;
+
+ return ftndesc;
+}
+
/**
- * common_call_trampoline:
+ * mini_add_method_wrappers_llvmonly:
+ *
+ * Add unbox/gsharedvt wrappers around COMPILED_METHOD if needed. Return the wrapper address or COMPILED_METHOD
+ * if no wrapper is needed. Set OUT_ARG to the rgctx/extra argument needed to be passed to the returned method.
+ */
+gpointer
+mini_add_method_wrappers_llvmonly (MonoMethod *m, gpointer compiled_method, gboolean caller_gsharedvt, gboolean add_unbox_tramp, gpointer *out_arg)
+{
+ gpointer addr;
+ gboolean callee_gsharedvt, callee_array_helper;
+ MonoMethod *jmethod = NULL;
+ MonoJitInfo *ji;
+
+ // FIXME: This loads information from AOT (perf problem)
+ ji = mini_jit_info_table_find (mono_domain_get (), (char *)mono_get_addr_from_ftnptr (compiled_method), NULL);
+ 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 (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);
+ }
+ }
+
+ g_assert (mono_llvm_only);
+ g_assert (out_arg);
+
+ if (ji && !ji->is_trampoline)
+ jmethod = jinfo_get_method (ji);
+
+ if (callee_gsharedvt)
+ callee_gsharedvt = mini_is_gsharedvt_variable_signature (mono_method_signature (jmethod));
+
+ if (!caller_gsharedvt && callee_gsharedvt) {
+ MonoMethodSignature *sig, *gsig;
+ gpointer wrapper_addr;
+
+ /* 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 */
+ sig = mono_method_signature (m);
+ gsig = mono_method_signature (jmethod);
+
+ wrapper_addr = mini_get_gsharedvt_wrapper (TRUE, addr, sig, gsig, -1, FALSE);
+
+ /*
+ * This is a gsharedvt in wrapper, it gets passed a ftndesc for the gsharedvt method as an argument.
+ */
+ *out_arg = mini_create_llvmonly_ftndesc (mono_domain_get (), addr, mini_method_get_rgctx (m));
+ addr = wrapper_addr;
+ //printf ("IN: %s\n", mono_method_full_name (m, TRUE));
+ }
+
+ if (!(*out_arg) && mono_method_needs_static_rgctx_invoke (m, FALSE))
+ *out_arg = mini_method_get_rgctx (m);
+
+ if (caller_gsharedvt && !callee_gsharedvt) {
+ /*
+ * The callee uses the gsharedvt calling convention, have to add an out wrapper.
+ */
+ gpointer out_wrapper = mini_get_gsharedvt_wrapper (FALSE, NULL, mono_method_signature (m), NULL, -1, FALSE);
+ MonoFtnDesc *out_wrapper_arg = mini_create_llvmonly_ftndesc (mono_domain_get (), addr, *out_arg);
+
+ addr = out_wrapper;
+ *out_arg = out_wrapper_arg;
+ }
+
+ return addr;
+}
+
+/**
+ * common_call_trampoline_inner:
*
* The code to handle normal, virtual, and interface method calls and jumps, both
* from JITted and LLVM compiled code.
*/
static gpointer
-common_call_trampoline_inner (mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVTable *vt, gpointer *vtable_slot)
+common_call_trampoline_inner (mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVTable *vt, gpointer *vtable_slot, MonoError *error)
{
gpointer addr, compiled_method;
gboolean generic_shared = FALSE;
MonoMethod *declaring = NULL;
MonoMethod *generic_virtual = NULL, *variant_iface = NULL;
int context_used;
- gboolean imt_call, virtual;
+ gboolean imt_call, virtual_;
gpointer *orig_vtable_slot, *vtable_slot_to_patch = NULL;
MonoJitInfo *ji = NULL;
- virtual = vt && (gpointer)vtable_slot > (gpointer)vt;
+ mono_error_init (error);
+
+ virtual_ = vt && (gpointer)vtable_slot > (gpointer)vt;
imt_call = vt && (gpointer)vtable_slot < (gpointer)vt;
/*
* rgctx trampolines are needed when the call is indirect so the caller can't pass
* the rgctx argument needed by the callee.
*/
- if (virtual && m)
+ if (virtual_ && m)
need_rgctx_tramp = mono_method_needs_static_rgctx_invoke (m, FALSE);
orig_vtable_slot = vtable_slot;
g_assert (vtable_slot);
imt_method = mono_arch_find_imt_method (regs, code);
- this_arg = mono_arch_get_this_arg_from_call (regs, code);
+ this_arg = (MonoObject *)mono_arch_get_this_arg_from_call (regs, code);
if (mono_object_is_transparent_proxy (this_arg)) {
/* Use the slow path for now */
* The virtual check is needed because is_generic_method_definition (m) could
* return TRUE for methods used in IMT calls too.
*/
- if (virtual && is_generic_method_definition (m)) {
+ if (virtual_ && is_generic_method_definition (m)) {
MonoError error;
MonoGenericContext context = { NULL, NULL };
MonoMethod *declaring;
klass = vtable->klass;
} else {
- MonoObject *this_argument = mono_arch_get_this_arg_from_call (regs, code);
+ MonoObject *this_argument = (MonoObject *)mono_arch_get_this_arg_from_call (regs, code);
vt = this_argument->vtable;
vtable_slot = orig_vtable_slot;
if (!code && mono_method_needs_static_rgctx_invoke (m, FALSE))
need_rgctx_tramp = TRUE;
- addr = compiled_method = mono_compile_method (m);
- g_assert (addr);
+ addr = compiled_method = mono_jit_compile_method (m, error);
+ if (!addr)
+ return NULL;
if (generic_virtual || variant_iface) {
if (vt->klass->valuetype) /*FIXME is this required variant iface?*/
GSList *list, *tmp;
mono_domain_lock (domain);
- list = g_hash_table_lookup (domain_jit_info (domain)->jump_target_got_slot_hash, m);
+ list = (GSList *)g_hash_table_lookup (domain_jit_info (domain)->jump_target_got_slot_hash, m);
if (list) {
for (tmp = list; tmp; tmp = tmp->next) {
- gpointer *got_slot = tmp->data;
+ gpointer *got_slot = (gpointer *)tmp->data;
*got_slot = addr;
}
g_hash_table_remove (domain_jit_info (domain)->jump_target_got_slot_hash, m);
if (plt_entry) {
if (generic_shared) {
target_ji =
- mini_jit_info_table_find (mono_domain_get (), mono_get_addr_from_ftnptr (compiled_method), NULL);
+ mini_jit_info_table_find (mono_domain_get (), (char *)mono_get_addr_from_ftnptr (compiled_method), NULL);
if (!ji)
ji = mini_jit_info_table_find (mono_domain_get (), (char*)code, NULL);
}
}
if (!no_patch)
- mono_aot_patch_plt_entry (code, plt_entry, NULL, regs, addr);
+ mono_aot_patch_plt_entry (code, plt_entry, NULL, regs, (guint8 *)addr);
} else {
if (generic_shared) {
if (m->wrapper_type != MONO_WRAPPER_NONE)
/* Patch calling code */
target_ji =
- mini_jit_info_table_find (mono_domain_get (), mono_get_addr_from_ftnptr (compiled_method), NULL);
+ mini_jit_info_table_find (mono_domain_get (), (char *)mono_get_addr_from_ftnptr (compiled_method), NULL);
if (!ji)
ji = mini_jit_info_table_find (mono_domain_get (), (char*)code, NULL);
}
if (!no_patch && mono_method_same_domain (ji, target_ji))
- mono_arch_patch_callsite (ji->code_start, code, addr);
+ mono_arch_patch_callsite ((guint8 *)ji->code_start, code, (guint8 *)addr);
}
}
}
static gpointer
-common_call_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVTable *vt, gpointer *vtable_slot)
+common_call_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVTable *vt, gpointer *vtable_slot, MonoError *error)
{
gpointer res;
MONO_PREPARE_RESET_BLOCKING;
- res = common_call_trampoline_inner (regs, code, m, vt, vtable_slot);
+ res = common_call_trampoline_inner (regs, code, m, vt, vtable_slot, error);
MONO_FINISH_RESET_BLOCKING;
return res;
}
gpointer
mono_magic_trampoline (mgreg_t *regs, guint8 *code, gpointer arg, guint8* tramp)
{
+ MonoError error;
+ gpointer res;
+
trampoline_calls ++;
- return common_call_trampoline (regs, code, arg, NULL, NULL);
+ res = common_call_trampoline (regs, code, (MonoMethod *)arg, NULL, NULL, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+ return res;
}
/**
MonoVTable *vt;
gpointer *vtable_slot;
MonoMethod *m;
- gpointer addr;
+ MonoError error;
+ gpointer addr, res;
trampoline_calls ++;
/*
* Obtain the vtable from the 'this' arg.
*/
- this_arg = mono_arch_get_this_arg_from_call (regs, code);
+ this_arg = (MonoObject *)mono_arch_get_this_arg_from_call (regs, code);
g_assert (this_arg);
vt = this_arg->vtable;
m = NULL;
}
- return common_call_trampoline (regs, code, m, vt, vtable_slot);
+ res = common_call_trampoline (regs, code, m, vt, vtable_slot, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+ return res;
}
#ifndef DISABLE_REMOTING
g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */;
m = mono_marshal_get_remoting_invoke_with_check (m);
- addr = mono_compile_method (m);
+ addr = mono_jit_compile_method (m, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
g_assert (addr);
return addr;
trampoline_calls ++;
- image = *(gpointer*)(gpointer)token_info;
+ image = (MonoImage *)*(gpointer*)(gpointer)token_info;
token_info += sizeof (gpointer);
token = *(guint32*)(gpointer)token_info;
addr = mono_aot_get_method_from_token (mono_domain_get (), image, token);
if (!addr) {
- method = mono_get_method (image, token, NULL);
- g_assert (method);
+ MonoError error;
+ method = mono_get_method_checked (image, token, NULL, NULL, &error);
+ if (!method)
+ g_error ("Could not load AOT trampoline due to %s", mono_error_get_message (&error));
/* Use the generic code */
return mono_magic_trampoline (regs, code, method, tramp);
plt_entry = mono_aot_get_plt_entry (code);
g_assert (plt_entry);
- mono_aot_patch_plt_entry (code, plt_entry, NULL, regs, addr);
+ mono_aot_patch_plt_entry (code, plt_entry, NULL, regs, (guint8 *)addr);
return addr;
}
{
guint32 plt_info_offset = mono_aot_get_plt_info_offset (regs, code);
gpointer res;
+ MonoError error;
trampoline_calls ++;
- res = mono_aot_plt_resolve (aot_module, plt_info_offset, code);
+ res = mono_aot_plt_resolve (aot_module, plt_info_offset, code, &error);
if (!res) {
- if (mono_loader_get_last_error ())
- mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+ if (mono_loader_get_last_error ()) {
+ MonoError error;
+
+ mono_error_init (&error);
+ mono_error_set_from_loader_error (&error);
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
// FIXME: Error handling (how ?)
g_assert (res);
}
gpointer arg = (gpointer)(gssize)r [MONO_ARCH_VTABLE_REG];
guint32 index = MONO_RGCTX_SLOT_INDEX (slot);
gboolean mrgctx = MONO_RGCTX_SLOT_IS_MRGCTX (slot);
+ MonoError error;
+ gpointer res;
trampoline_calls ++;
num_lookups++;
if (mrgctx)
- return mono_method_fill_runtime_generic_context (arg, index);
+ res = mono_method_fill_runtime_generic_context ((MonoMethodRuntimeGenericContext *)arg, index, &error);
else
- return mono_class_fill_runtime_generic_context (arg, index);
+ res = mono_class_fill_runtime_generic_context ((MonoVTable *)arg, index, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+ return res;
}
/*
invoke = mono_get_delegate_invoke (klass);
g_assert (invoke);
- tramp_data = mono_domain_alloc0 (domain, sizeof (MonoDelegateTrampInfo));
+ tramp_data = (MonoDelegateTrampInfo *)mono_domain_alloc0 (domain, sizeof (MonoDelegateTrampInfo));
tramp_data->invoke = invoke;
tramp_data->invoke_sig = mono_method_signature (invoke);
tramp_data->impl_this = mono_arch_get_delegate_invoke_impl (mono_method_signature (invoke), TRUE);
MonoJitInfo *ji;
MonoMethod *m;
MonoMethod *method = NULL;
+ MonoError error;
gboolean multicast, callvirt = FALSE, closed_over_null = FALSE;
gboolean need_rgctx_tramp = FALSE;
gboolean need_unbox_tramp = FALSE;
gboolean enable_caching = TRUE;
MonoDelegateTrampInfo *tramp_info = (MonoDelegateTrampInfo*)arg;
MonoMethod *invoke = tramp_info->invoke;
- guint8 *impl_this = tramp_info->impl_this;
- guint8 *impl_nothis = tramp_info->impl_nothis;
+ guint8 *impl_this = (guint8 *)tramp_info->impl_this;
+ guint8 *impl_nothis = (guint8 *)tramp_info->impl_nothis;
MonoError err;
MonoMethodSignature *sig;
gpointer addr, compiled_method;
trampoline_calls ++;
/* Obtain the delegate object according to the calling convention */
- delegate = mono_arch_get_this_arg_from_call (regs, code);
+ delegate = (MonoDelegate *)mono_arch_get_this_arg_from_call (regs, code);
g_assert (mono_class_has_parent (mono_object_class (delegate), mono_defaults.multicastdelegate_class));
if (delegate->method) {
if (!(sig && method == tramp_info->method)) {
mono_error_init (&err);
sig = mono_method_signature_checked (method, &err);
- if (!sig)
- mono_error_raise_exception (&err);
+ if (!sig) {
+ mono_error_set_pending_exception (&err);
+ return NULL;
+ }
}
if (sig->hasthis && method->klass->valuetype) {
// ftnptrs are being used. "method" would end up null on archtitectures without
// ftnptrs so we can just skip this.
} else if (delegate->method_ptr) {
- ji = mono_jit_info_table_find (domain, mono_get_addr_from_ftnptr (delegate->method_ptr));
+ ji = mono_jit_info_table_find (domain, (char *)mono_get_addr_from_ftnptr (delegate->method_ptr));
if (ji)
method = jinfo_get_method (ji);
}
if (!(sig && method == tramp_info->method)) {
mono_error_init (&err);
sig = mono_method_signature_checked (method, &err);
- if (!sig)
- mono_error_raise_exception (&err);
+ if (!sig) {
+ mono_error_set_pending_exception (&err);
+ return NULL;
+ }
}
callvirt = !delegate->target && sig->hasthis;
if (enable_caching && delegate->method_code && *delegate->method_code) {
delegate->method_ptr = *delegate->method_code;
} else {
- compiled_method = addr = mono_compile_method (method);
+ compiled_method = addr = mono_jit_compile_method (method, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
addr = mini_add_method_trampoline (method, compiled_method, need_rgctx_tramp, need_unbox_tramp);
delegate->method_ptr = addr;
if (enable_caching && delegate->method_code)
- *delegate->method_code = delegate->method_ptr;
+ *delegate->method_code = (guint8 *)delegate->method_ptr;
}
} else {
if (need_rgctx_tramp)
if (!code) {
/* The general, unoptimized case */
m = mono_marshal_get_delegate_invoke (invoke, delegate);
- code = mono_compile_method (m);
- code = mini_add_method_trampoline (m, code, mono_method_needs_static_rgctx_invoke (m, FALSE), FALSE);
+ code = (guint8 *)mono_jit_compile_method (m, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+ code = (guint8 *)mini_add_method_trampoline (m, code, mono_method_needs_static_rgctx_invoke (m, FALSE), FALSE);
}
delegate->invoke_impl = mono_get_addr_from_ftnptr (code);
{
MonoContext ctx;
MonoException *exc;
- MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id);
+ MonoJitTlsData *jit_tls = (MonoJitTlsData *)mono_native_tls_get_value (mono_jit_tls_id);
gpointer resume_ip = jit_tls->handler_block_return_address;
memcpy (&ctx, &jit_tls->handler_block_context, sizeof (MonoContext));
exc = mono_thread_resume_interruption ();
if (exc) {
- mono_handle_exception (&ctx, exc);
+ mono_handle_exception (&ctx, (MonoObject *)exc);
mono_restore_context (&ctx);
}
void
mono_trampolines_init (void)
{
- mono_mutex_init_recursive (&trampolines_mutex);
+ mono_os_mutex_init_recursive (&trampolines_mutex);
if (mono_aot_only)
return;
if (rgctx_lazy_fetch_trampoline_hash_addr)
g_hash_table_destroy (rgctx_lazy_fetch_trampoline_hash_addr);
- mono_mutex_destroy (&trampolines_mutex);
+ mono_os_mutex_destroy (&trampolines_mutex);
}
guint8 *
gpointer
mono_create_jump_trampoline (MonoDomain *domain, MonoMethod *method, gboolean add_sync_wrapper)
{
+ MonoError error;
MonoJitInfo *ji;
gpointer code;
guint32 code_size = 0;
if (code && !ji->has_generic_jit_info && !(method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED))
return code;
- if (mono_llvm_only)
- return mono_jit_compile_method (method);
+ if (mono_llvm_only) {
+ code = mono_jit_compile_method (method, &error);
+ if (!mono_error_ok (&error))
+ mono_error_raise_exception (&error);
+ return code;
+ }
mono_domain_lock (domain);
code = g_hash_table_lookup (domain_jit_info (domain)->jump_trampoline_hash, method);
code = mono_create_specific_trampoline (method, MONO_TRAMPOLINE_JUMP, mono_domain_get (), &code_size);
g_assert (code_size);
- ji = mono_domain_alloc0 (domain, MONO_SIZEOF_JIT_INFO);
+ ji = (MonoJitInfo *)mono_domain_alloc0 (domain, MONO_SIZEOF_JIT_INFO);
ji->code_start = code;
ji->code_size = code_size;
ji->d.method = method;
gpointer
mono_create_jit_trampoline_in_domain (MonoDomain *domain, MonoMethod *method)
{
+ MonoError error;
gpointer tramp;
if (mono_aot_only) {
/* These wrappers are not generated */
return method_not_found;
/* Methods are lazily initialized on first call, so this can't lead recursion */
- return mono_compile_method (method);
+ code = mono_jit_compile_method (method, &error);
+ if (!mono_error_ok (&error))
+ mono_error_raise_exception (&error);
+ return code;
}
}
MonoDomain *domain = mono_domain_get ();
guint8 *buf, *start;
- buf = start = mono_domain_alloc0 (domain, 2 * sizeof (gpointer));
+ buf = start = (guint8 *)mono_domain_alloc0 (domain, 2 * sizeof (gpointer));
*(gpointer*)(gpointer)buf = image;
buf += sizeof (gpointer);
pair.klass = klass;
pair.method = method;
mono_domain_lock (domain);
- tramp_info = g_hash_table_lookup (domain_jit_info (domain)->delegate_trampoline_hash, &pair);
+ tramp_info = (MonoDelegateTrampInfo *)g_hash_table_lookup (domain_jit_info (domain)->delegate_trampoline_hash, &pair);
mono_domain_unlock (domain);
if (tramp_info)
return tramp_info;
tramp_info->invoke_impl = mono_create_specific_trampoline (tramp_info, MONO_TRAMPOLINE_DELEGATE, domain, &code_size);
g_assert (code_size);
- dpair = mono_domain_alloc0 (domain, sizeof (MonoClassMethodPair));
+ dpair = (MonoClassMethodPair *)mono_domain_alloc0 (domain, sizeof (MonoClassMethodPair));
memcpy (dpair, &pair, sizeof (MonoClassMethodPair));
/* store trampoline address */
return ptr;
}
-
-#ifdef MONO_ARCH_LLVM_SUPPORTED
-/*
- * mono_create_llvm_imt_trampoline:
- *
- * LLVM compiled code can't pass in the IMT argument, so we use this trampoline, which
- * sets the IMT argument, then branches to the contents of the vtable slot given by
- * vt_offset in the vtable which is obtained from the argument list.
- */
-gpointer
-mono_create_llvm_imt_trampoline (MonoDomain *domain, MonoMethod *m, int vt_offset)
-{
-#ifdef MONO_ARCH_HAVE_LLVM_IMT_TRAMPOLINE
- return mono_arch_get_llvm_imt_trampoline (domain, m, vt_offset);
-#else
- g_assert_not_reached ();
- return NULL;
-#endif
-}
-#endif
guint32
mono_find_rgctx_lazy_fetch_trampoline_by_addr (gconstpointer addr)