-/*
+/**
+ * \file
* (C) 2003 Ximian, Inc.
* (C) 2003-2011 Novell, Inc.
* Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
#include <mono/utils/mono-threads-coop.h>
#include "mini.h"
+#include "lldb.h"
+
+#ifdef ENABLE_INTERPRETER
+#include "interp/interp.h"
+#endif
/*
* Address of the trampoline code. This is used by the debugger to check
/**
* mono_create_static_rgctx_trampoline:
- * @m: the mono method to create a trampoline for
- * @addr: the address to jump to (where the compiled code for M lives)
+ * \param m the mono method to create a trampoline for
+ * \param addr the address to jump to (where the compiled code for M lives)
*
* Creates a static rgctx trampoline for M which branches to ADDR which should
* point to the compiled code of M.
*
* On PPC addr should be an ftnptr and the return value is an ftnptr too.
*
- * Returns the generated static rgctx trampoline.
+ * \returns the generated static rgctx trampoline.
*/
gpointer
mono_create_static_rgctx_trampoline (MonoMethod *m, gpointer addr)
if (mono_aot_only)
res = mono_aot_get_static_rgctx_trampoline (ctx, addr);
else
- res = mono_arch_get_static_rgctx_trampoline (m, (MonoMethodRuntimeGenericContext *)ctx, addr);
+ res = mono_arch_get_static_rgctx_trampoline (ctx, addr);
mono_domain_lock (domain);
/* Duplicates inserted while we didn't hold the lock are OK */
g_assert (imt_slot < MONO_IMT_SIZE);
- mono_error_init (error);
+ 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)
/* 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);
mono_error_assert_ok (error);
gpointer *orig_vtable_slot, *vtable_slot_to_patch = NULL;
MonoJitInfo *ji = NULL;
- mono_error_init (error);
+ error_init (error);
virtual_ = vt && (gpointer)vtable_slot > (gpointer)vt;
imt_call = vt && (gpointer)vtable_slot < (gpointer)vt;
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);
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);
mono_magic_trampoline (mgreg_t *regs, guint8 *code, gpointer arg, guint8* tramp)
{
gpointer res;
+ MonoError error;
- MONO_ENTER_GC_UNSAFE_UNBALANCED;
+ MONO_REQ_GC_UNSAFE_MODE;
- MonoError error;
+ g_assert (mono_thread_is_gc_unsafe_mode ());
trampoline_calls ++;
res = common_call_trampoline (regs, code, (MonoMethod *)arg, NULL, NULL, &error);
- mono_error_set_pending_exception (&error);
-
- mono_interruption_checkpoint_from_trampoline ();
-
- MONO_EXIT_GC_UNSAFE_UNBALANCED;
+ if (!is_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
return res;
}
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)
* 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 () &&
if (!is_remote) {
sig = tramp_info->sig;
if (!(sig && method == tramp_info->method)) {
- mono_error_init (&err);
+ error_init (&err);
sig = mono_method_signature_checked (method, &err);
if (!sig) {
mono_error_set_pending_exception (&err);
if (method) {
sig = tramp_info->sig;
if (!(sig && method == tramp_info->method)) {
- mono_error_init (&err);
+ error_init (&err);
sig = mono_method_signature_checked (method, &err);
if (!sig) {
mono_error_set_pending_exception (&err);
* 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;
}
return code;
}
-#ifdef MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD
-static gpointer
-mono_handler_block_guard_trampoline (mgreg_t *regs, guint8 *code, gpointer *tramp_info, guint8* tramp)
-{
- MONO_REQ_GC_UNSAFE_MODE;
-
- MonoContext ctx;
- MonoException *exc;
- 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));
- MONO_CONTEXT_SET_IP (&ctx, jit_tls->handler_block_return_address);
-
- jit_tls->handler_block_return_address = NULL;
- jit_tls->handler_block = NULL;
-
- if (!resume_ip) /*this should not happen, but we should avoid crashing */
- exc = mono_get_exception_execution_engine ("Invalid internal state, resuming abort after handler block but no resume ip found");
- else
- exc = mono_thread_resume_interruption ();
-
- if (exc) {
- mono_handle_exception (&ctx, (MonoObject *)exc);
- mono_restore_context (&ctx);
- }
-
- return resume_ip;
-}
-
-gpointer
-mono_create_handler_block_trampoline (void)
-{
- static gpointer 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;
- }
-
- mono_trampolines_lock ();
- if (!code) {
- MonoTrampInfo *info;
- gpointer tmp;
-
- tmp = mono_arch_create_handler_block_trampoline (&info, FALSE);
- mono_tramp_info_register (info, NULL);
- mono_memory_barrier ();
- code = tmp;
- }
- mono_trampolines_unlock ();
-
- return code;
-}
-#endif
-
/*
* mono_get_trampoline_func:
*
#endif
case MONO_TRAMPOLINE_VCALL:
return mono_vcall_trampoline;
-#ifdef MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD
- case MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD:
- return mono_handler_block_guard_trampoline;
-#endif
default:
g_assert_not_reached ();
return NULL;
mono_trampoline_code [MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING] = create_trampoline_code (MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING);
#endif
mono_trampoline_code [MONO_TRAMPOLINE_VCALL] = create_trampoline_code (MONO_TRAMPOLINE_VCALL);
-#ifdef MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD
- mono_trampoline_code [MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD] = create_trampoline_code (MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD);
- mono_create_handler_block_trampoline ();
-#endif
mono_counters_register ("Calls to trampolines", MONO_COUNTER_JIT | MONO_COUNTER_INT, &trampoline_calls);
mono_counters_register ("JIT trampolines", MONO_COUNTER_JIT | MONO_COUNTER_INT, &jit_trampolines);
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
gpointer code;
guint32 code_size = 0;
- mono_error_init (error);
+ error_init (error);
+
+#ifdef ENABLE_INTERPRETER
+ if (mono_use_interpreter) {
+ gpointer ret = mono_interp_create_trampoline (domain, method, error);
+ if (!mono_error_ok (error))
+ return NULL;
+ return ret;
+ }
+#endif
code = mono_jit_find_compiled_method_with_jit_info (domain, method, &ji);
/*
{
gpointer tramp;
- mono_error_init (error);
+ error_init (error);
if (mono_aot_only) {
if (mono_llvm_only && method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
tramp_info->impl_nothis = mono_arch_get_delegate_invoke_impl (mono_method_signature (invoke), FALSE);
tramp_info->method = method;
if (method) {
- mono_error_init (&error);
+ error_init (&error);
tramp_info->sig = mono_method_signature_checked (method, &error);
tramp_info->need_rgctx_tramp = mono_method_needs_static_rgctx_invoke (method, FALSE);
}
gpointer
mono_create_delegate_trampoline (MonoDomain *domain, MonoClass *klass)
{
- if (mono_llvm_only)
+ if (mono_llvm_only || mono_use_interpreter)
return no_delegate_trampoline;
return mono_create_delegate_trampoline_info (domain, klass, NULL)->invoke_impl;
"delegate",
"restore_stack_prot",
"generic_virtual_remoting",
- "vcall",
- "handler_block_guard"
+ "vcall"
};
/*