#include <mono/metadata/gc-internals.h>
#include <mono/metadata/verify-internals.h>
#include <mono/metadata/reflection-internals.h>
+#include <mono/metadata/w32event.h>
#include <mono/utils/strenc.h>
#include <mono/utils/mono-counters.h>
#include <mono/utils/mono-error-internals.h>
#define ldstr_unlock() mono_os_mutex_unlock (&ldstr_section)
static mono_mutex_t ldstr_section;
+
/**
* mono_runtime_object_init:
* @this_obj: the object to initialize
#ifndef DISABLE_REMOTING
static gpointer
-default_remoting_trampoline (MonoDomain *domain, MonoMethod *method, MonoRemotingTarget target, MonoError *error)
+create_remoting_trampoline (MonoDomain *domain, MonoMethod *method, MonoRemotingTarget target, MonoError *error)
{
- g_error ("remoting not installed");
- return NULL;
+ if (!callbacks.create_remoting_trampoline)
+ g_error ("remoting not installed");
+ return callbacks.create_remoting_trampoline (domain, method, target, error);
}
-static MonoRemotingTrampoline arch_create_remoting_trampoline = default_remoting_trampoline;
#endif
-static gpointer
-default_delegate_trampoline (MonoDomain *domain, MonoClass *klass)
-{
- g_assert_not_reached ();
- return NULL;
-}
-
-static MonoDelegateTrampoline arch_create_delegate_trampoline = default_delegate_trampoline;
-static MonoImtThunkBuilder imt_thunk_builder;
-static gboolean always_build_imt_thunks;
+static MonoImtTrampolineBuilder imt_trampoline_builder;
+static gboolean always_build_imt_trampolines;
#if (MONO_IMT_SIZE > 32)
#error "MONO_IMT_SIZE cannot be larger than 32"
return &callbacks;
}
-#ifndef DISABLE_REMOTING
void
-mono_install_remoting_trampoline (MonoRemotingTrampoline func)
+mono_install_imt_trampoline_builder (MonoImtTrampolineBuilder func)
{
- arch_create_remoting_trampoline = func? func: default_remoting_trampoline;
+ imt_trampoline_builder = func;
}
-#endif
void
-mono_install_delegate_trampoline (MonoDelegateTrampoline func)
+mono_set_always_build_imt_trampolines (gboolean value)
{
- arch_create_delegate_trampoline = func? func: default_delegate_trampoline;
-}
-
-void
-mono_install_imt_thunk_builder (MonoImtThunkBuilder func) {
- imt_thunk_builder = func;
-}
-
-void
-mono_set_always_build_imt_thunks (gboolean value)
-{
- always_build_imt_thunks = value;
+ always_build_imt_trampolines = value;
}
/**
mono_error_init (error);
- if (!callbacks.compile_method) {
- g_error ("compile method called on uninitialized runtime");
- return NULL;
- }
+ g_assert (callbacks.compile_method);
res = callbacks.compile_method (method, error);
return res;
}
{
MONO_REQ_GC_NEUTRAL_MODE
- return arch_create_delegate_trampoline (mono_domain_get (), klass);
-}
-
-static MonoFreeMethodFunc default_mono_free_method = NULL;
-
-/**
- * mono_install_free_method:
- * @func: pointer to the MonoFreeMethodFunc used to release a method
- *
- * This is an internal VM routine, it is used for the engines to
- * register a handler to release the resources associated with a method.
- *
- * Methods are freed when no more references to the delegate that holds
- * them are left.
- */
-void
-mono_install_free_method (MonoFreeMethodFunc func)
-{
- default_mono_free_method = func;
+ g_assert (callbacks.create_delegate_trampoline);
+ return callbacks.create_delegate_trampoline (mono_domain_get (), klass);
}
/**
{
MONO_REQ_GC_NEUTRAL_MODE
- if (default_mono_free_method != NULL)
- default_mono_free_method (domain, method);
+ if (callbacks.free_method)
+ callbacks.free_method (domain, method);
mono_method_clear_object (domain, method);
break;
}
- free (hashes_start);
+ g_free (hashes_start);
/* Report the result */
return c % MONO_IMT_SIZE;
}
imt_emit_ir (sorted_array, 0, number_of_entries, result);
- free (sorted_array);
+ g_free (sorted_array);
return result;
}
MONO_REQ_GC_NEUTRAL_MODE;
if (imt_builder_entry != NULL) {
- if (imt_builder_entry->children == 0 && !fail_tramp && !always_build_imt_thunks) {
+ if (imt_builder_entry->children == 0 && !fail_tramp && !always_build_imt_trampolines) {
/* No collision, return the vtable slot contents */
return vtable->vtable [imt_builder_entry->value.vtable_slot];
} else {
- /* Collision, build the thunk */
+ /* Collision, build the trampoline */
GPtrArray *imt_ir = imt_sort_slot_entries (imt_builder_entry);
gpointer result;
int i;
- result = imt_thunk_builder (vtable, domain,
+ result = imt_trampoline_builder (vtable, domain,
(MonoIMTCheckItem**)imt_ir->pdata, imt_ir->len, fail_tramp);
for (i = 0; i < imt_ir->len; ++i)
g_free (g_ptr_array_index (imt_ir, i));
mono_class_setup_methods (iface);
vt_slot = interface_offset;
- for (method_slot_in_interface = 0; method_slot_in_interface < iface->method.count; method_slot_in_interface++) {
+ int mcount = mono_class_get_method_count (iface);
+ for (method_slot_in_interface = 0; method_slot_in_interface < mcount; method_slot_in_interface++) {
MonoMethod *method;
- if (slot_num >= 0 && iface->is_inflated) {
+ if (slot_num >= 0 && mono_class_is_ginst (iface)) {
/*
* The imt slot of the method is the same as for its declaring method,
* see the comment in mono_method_get_imt_slot (), so we can
* avoid inflating methods which will be discarded by
* add_imt_builder_entry anyway.
*/
- method = mono_class_get_method_by_index (iface->generic_class->container_class, method_slot_in_interface);
+ method = mono_class_get_method_by_index (mono_class_get_generic_class (iface)->container_class, method_slot_in_interface);
if (mono_method_get_imt_slot (method) != slot_num) {
vt_slot ++;
continue;
for (list_item = extra_interfaces; list_item != NULL; list_item=list_item->next) {
MonoClass* iface = (MonoClass *)list_item->data;
int method_slot_in_interface;
- for (method_slot_in_interface = 0; method_slot_in_interface < iface->method.count; method_slot_in_interface++) {
+ int mcount = mono_class_get_method_count (iface);
+ for (method_slot_in_interface = 0; method_slot_in_interface < mcount; method_slot_in_interface++) {
MonoMethod *method = mono_class_get_method_by_index (iface, method_slot_in_interface);
if (method->is_generic)
has_generic_virtual = TRUE;
add_imt_builder_entry (imt_builder, method, &imt_collisions_bitmap, interface_offset + method_slot_in_interface, slot_num);
}
- interface_offset += iface->method.count;
+ interface_offset += mcount;
}
}
for (i = 0; i < MONO_IMT_SIZE; ++i) {
if (has_generic_virtual || has_variant_iface) {
/*
- * There might be collisions later when the the thunk is expanded.
+ * There might be collisions later when the the trampoline is expanded.
*/
imt_collisions_bitmap |= (1 << i);
/*
- * The IMT thunk might be called with an instance of one of the
+ * The IMT trampoline might be called with an instance of one of the
* generic virtual methods, so has to fallback to the IMT trampoline.
*/
imt [i] = initialize_imt_slot (vt, domain, imt_builder [i], callbacks.get_imt_trampoline (vt, i));
entry = next;
}
}
- free (imt_builder);
+ g_free (imt_builder);
/* we OR the bitmap since we may build just a single imt slot at a time */
vt->imt_collisions_bitmap |= imt_collisions_bitmap;
}
* @imt_slot: slot in the IMT table
*
* Fill the given @imt_slot in the IMT table of @vtable with
- * a trampoline or a thunk for the case of collisions.
+ * a trampoline or a trampoline for the case of collisions.
* This is part of the internal mono API.
*
* LOCKING: Take the domain lock.
mono_loader_unlock ();
}
-
-/*
- * The first two free list entries both belong to the wait list: The
- * first entry is the pointer to the head of the list and the second
- * entry points to the last element. That way appending and removing
- * the first element are both O(1) operations.
- */
-#ifdef MONO_SMALL_CONFIG
-#define NUM_FREE_LISTS 6
-#else
-#define NUM_FREE_LISTS 12
-#endif
-#define FIRST_FREE_LIST_SIZE 64
-#define MAX_WAIT_LENGTH 50
#define THUNK_THRESHOLD 10
-/*
- * LOCKING: The domain lock must be held.
- */
-static void
-init_thunk_free_lists (MonoDomain *domain)
-{
- MONO_REQ_GC_NEUTRAL_MODE;
-
- if (domain->thunk_free_lists)
- return;
- domain->thunk_free_lists = (MonoThunkFreeList **)mono_domain_alloc0 (domain, sizeof (gpointer) * NUM_FREE_LISTS);
-}
-
-static int
-list_index_for_size (int item_size)
-{
- int i = 2;
- int size = FIRST_FREE_LIST_SIZE;
-
- while (item_size > size && i < NUM_FREE_LISTS - 1) {
- i++;
- size <<= 1;
- }
-
- return i;
-}
-
/**
- * mono_method_alloc_generic_virtual_thunk:
+ * mono_method_alloc_generic_virtual_trampoline:
* @domain: a domain
* @size: size in bytes
*
* Allocs size bytes to be used for the code of a generic virtual
- * thunk. It's either allocated from the domain's code manager or
+ * trampoline. It's either allocated from the domain's code manager or
* reused from a previously invalidated piece.
*
* LOCKING: The domain lock must be held.
*/
gpointer
-mono_method_alloc_generic_virtual_thunk (MonoDomain *domain, int size)
+mono_method_alloc_generic_virtual_trampoline (MonoDomain *domain, int size)
{
MONO_REQ_GC_NEUTRAL_MODE;
static gboolean inited = FALSE;
- static int generic_virtual_thunks_size = 0;
-
- guint32 *p;
- int i;
- MonoThunkFreeList **l;
-
- init_thunk_free_lists (domain);
-
- size += sizeof (guint32);
- if (size < sizeof (MonoThunkFreeList))
- size = sizeof (MonoThunkFreeList);
+ static int generic_virtual_trampolines_size = 0;
- i = list_index_for_size (size);
- for (l = &domain->thunk_free_lists [i]; *l; l = &(*l)->next) {
- if ((*l)->size >= size) {
- MonoThunkFreeList *item = *l;
- *l = item->next;
- return ((guint32*)item) + 1;
- }
- }
-
- /* no suitable item found - search lists of larger sizes */
- while (++i < NUM_FREE_LISTS) {
- MonoThunkFreeList *item = domain->thunk_free_lists [i];
- if (!item)
- continue;
- g_assert (item->size > size);
- domain->thunk_free_lists [i] = item->next;
- return ((guint32*)item) + 1;
- }
-
- /* still nothing found - allocate it */
if (!inited) {
- mono_counters_register ("Generic virtual thunk bytes",
- MONO_COUNTER_GENERICS | MONO_COUNTER_INT, &generic_virtual_thunks_size);
+ mono_counters_register ("Generic virtual trampoline bytes",
+ MONO_COUNTER_GENERICS | MONO_COUNTER_INT, &generic_virtual_trampolines_size);
inited = TRUE;
}
- generic_virtual_thunks_size += size;
-
- p = (guint32 *)mono_domain_code_reserve (domain, size);
- *p = size;
+ generic_virtual_trampolines_size += size;
- mono_domain_lock (domain);
- if (!domain->generic_virtual_thunks)
- domain->generic_virtual_thunks = g_hash_table_new (NULL, NULL);
- g_hash_table_insert (domain->generic_virtual_thunks, p, p);
- mono_domain_unlock (domain);
-
- return p + 1;
-}
-
-/*
- * LOCKING: The domain lock must be held.
- */
-static void
-invalidate_generic_virtual_thunk (MonoDomain *domain, gpointer code)
-{
- MONO_REQ_GC_NEUTRAL_MODE;
-
- guint32 *p = (guint32 *)code;
- MonoThunkFreeList *l = (MonoThunkFreeList*)(p - 1);
- gboolean found = FALSE;
-
- mono_domain_lock (domain);
- if (!domain->generic_virtual_thunks)
- domain->generic_virtual_thunks = g_hash_table_new (NULL, NULL);
- if (g_hash_table_lookup (domain->generic_virtual_thunks, l))
- found = TRUE;
- mono_domain_unlock (domain);
-
- if (!found)
- /* Not allocated by mono_method_alloc_generic_virtual_thunk (), i.e. AOT */
- return;
- init_thunk_free_lists (domain);
-
- while (domain->thunk_free_lists [0] && domain->thunk_free_lists [0]->length >= MAX_WAIT_LENGTH) {
- MonoThunkFreeList *item = domain->thunk_free_lists [0];
- int length = item->length;
- int i;
-
- /* unlink the first item from the wait list */
- domain->thunk_free_lists [0] = item->next;
- domain->thunk_free_lists [0]->length = length - 1;
-
- i = list_index_for_size (item->size);
-
- /* put it in the free list */
- item->next = domain->thunk_free_lists [i];
- domain->thunk_free_lists [i] = item;
- }
-
- l->next = NULL;
- if (domain->thunk_free_lists [1]) {
- domain->thunk_free_lists [1] = domain->thunk_free_lists [1]->next = l;
- domain->thunk_free_lists [0]->length++;
- } else {
- g_assert (!domain->thunk_free_lists [0]);
-
- domain->thunk_free_lists [0] = domain->thunk_free_lists [1] = l;
- domain->thunk_free_lists [0]->length = 1;
- }
+ return mono_domain_code_reserve (domain, size);
}
typedef struct _GenericVirtualCase {
* Registers a call via unmanaged code to a generic virtual method
* instantiation or variant interface method. If the number of calls reaches a threshold
* (THUNK_THRESHOLD), the method is added to the vtable slot's generic
- * virtual method thunk.
+ * virtual method trampoline.
*/
void
mono_method_add_generic_virtual_invocation (MonoDomain *domain, MonoVTable *vtable,
static gboolean inited = FALSE;
static int num_added = 0;
+ static int num_freed = 0;
GenericVirtualCase *gvc, *list;
MonoImtBuilderEntry *entries;
if (!domain->generic_virtual_cases)
domain->generic_virtual_cases = g_hash_table_new (mono_aligned_addr_hash, NULL);
+ if (!inited) {
+ mono_counters_register ("Generic virtual cases", MONO_COUNTER_GENERICS | MONO_COUNTER_INT, &num_added);
+ mono_counters_register ("Freed IMT trampolines", MONO_COUNTER_GENERICS | MONO_COUNTER_INT, &num_freed);
+ inited = TRUE;
+ }
+
/* Check whether the case was already added */
list = (GenericVirtualCase *)g_hash_table_lookup (domain->generic_virtual_cases, vtable_slot);
gvc = list;
g_hash_table_insert (domain->generic_virtual_cases, vtable_slot, gvc);
- if (!inited) {
- mono_counters_register ("Generic virtual cases", MONO_COUNTER_GENERICS | MONO_COUNTER_INT, &num_added);
- inited = TRUE;
- }
num_added++;
}
int displacement = (gpointer*)vtable_slot - (gpointer*)vtable;
int imt_slot = MONO_IMT_SIZE + displacement;
- /* Force the rebuild of the thunk at the next call */
+ /* Force the rebuild of the trampoline at the next call */
imt_trampoline = callbacks.get_imt_trampoline (vtable, imt_slot);
*vtable_slot = imt_trampoline;
} else {
sorted = imt_sort_slot_entries (entries);
- *vtable_slot = imt_thunk_builder (NULL, domain, (MonoIMTCheckItem**)sorted->pdata, sorted->len,
- vtable_trampoline);
+ *vtable_slot = imt_trampoline_builder (NULL, domain, (MonoIMTCheckItem**)sorted->pdata, sorted->len,
+ vtable_trampoline);
while (entries) {
MonoImtBuilderEntry *next = entries->next;
for (i = 0; i < sorted->len; ++i)
g_free (g_ptr_array_index (sorted, i));
g_ptr_array_free (sorted, TRUE);
- }
-#ifndef __native_client__
- /* We don't re-use any thunks as there is a lot of overhead */
- /* to deleting and re-using code in Native Client. */
- if (old_thunk != vtable_trampoline && old_thunk != imt_trampoline)
- invalidate_generic_virtual_thunk (domain, old_thunk);
-#endif
+ if (old_thunk != vtable_trampoline && old_thunk != imt_trampoline)
+ num_freed ++;
+ }
}
mono_domain_unlock (domain);
if (mono_class_has_failure (element_class)) {
/*Can happen if element_class only got bad after mono_class_setup_vtable*/
if (!mono_class_has_failure (klass))
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "");
mono_domain_unlock (domain);
mono_loader_unlock ();
mono_error_set_for_class_failure (error, klass);
if (!klass->vtable_size)
mono_class_setup_vtable (klass);
- if (klass->generic_class && !klass->vtable)
+ if (mono_class_is_ginst (klass) && !klass->vtable)
mono_class_check_vtable_constraints (klass, NULL);
/* Initialize klass->has_finalize */
MONO_REQ_GC_UNSAFE_MODE;
MonoVTable *vt, *pvt;
- int i, j, vtsize, max_interface_id, extra_interface_vtsize = 0;
+ int i, j, vtsize, extra_interface_vtsize = 0;
+ guint32 max_interface_id;
MonoClass *k;
GSList *extra_interfaces = NULL;
MonoClass *klass = remote_class->proxy_class;
MonoMethod *cm;
if ((cm = klass->vtable [i])) {
- pvt->vtable [i] = arch_create_remoting_trampoline (domain, cm, target_type, error);
+ pvt->vtable [i] = create_remoting_trampoline (domain, cm, target_type, error);
if (!is_ok (error))
goto failure;
} else
pvt->vtable [i] = NULL;
}
- if (klass->flags & TYPE_ATTRIBUTE_ABSTRACT) {
+ if (mono_class_is_abstract (klass)) {
/* create trampolines for abstract methods */
for (k = klass; k; k = k->parent) {
MonoMethod* m;
gpointer iter = NULL;
while ((m = mono_class_get_methods (k, &iter)))
if (!pvt->vtable [m->slot]) {
- pvt->vtable [m->slot] = arch_create_remoting_trampoline (domain, m, target_type, error);
+ pvt->vtable [m->slot] = create_remoting_trampoline (domain, m, target_type, error);
if (!is_ok (error))
goto failure;
}
iter = NULL;
j = 0;
while ((cm = mono_class_get_methods (interf, &iter))) {
- pvt->vtable [slot + j++] = arch_create_remoting_trampoline (domain, cm, target_type, error);
+ pvt->vtable [slot + j++] = create_remoting_trampoline (domain, cm, target_type, error);
if (!is_ok (error))
goto failure;
}
int i, j;
if (remote_class == NULL) {
- if (extra_class->flags & TYPE_ATTRIBUTE_INTERFACE) {
+ if (mono_class_is_interface (extra_class)) {
key = (void **)g_malloc (sizeof(gpointer) * 3);
key [0] = GINT_TO_POINTER (2);
key [1] = mono_defaults.marshalbyrefobject_class;
key [1] = extra_class;
}
} else {
- if (extra_class != NULL && (extra_class->flags & TYPE_ATTRIBUTE_INTERFACE)) {
+ if (extra_class != NULL && mono_class_is_interface (extra_class)) {
key = (void **)g_malloc (sizeof(gpointer) * (remote_class->interface_count + 3));
key [0] = GINT_TO_POINTER (remote_class->interface_count + 2);
key [1] = remote_class->proxy_class;
g_free (key);
key = mp_key;
- if (proxy_class->flags & TYPE_ATTRIBUTE_INTERFACE) {
+ if (mono_class_is_interface (proxy_class)) {
rc = (MonoRemoteClass *)mono_domain_alloc (domain, MONO_SIZEOF_REMOTE_CLASS + sizeof(MonoClass*));
rc->interface_count = 1;
rc->interfaces [0] = proxy_class;
g_free (key);
key = mp_key;
- if (extra_class->flags & TYPE_ATTRIBUTE_INTERFACE) {
+ if (mono_class_is_interface (extra_class)) {
int i,j;
rc = (MonoRemoteClass *)mono_domain_alloc (domain, MONO_SIZEOF_REMOTE_CLASS + sizeof(MonoClass*) * (remote_class->interface_count + 1));
rc->proxy_class = remote_class->proxy_class;
tproxy = (MonoTransparentProxy*) proxy_object;
remote_class = tproxy->remote_class;
- if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
+ if (mono_class_is_interface (klass)) {
int i;
redo_vtable = TRUE;
for (i = 0; i < remote_class->interface_count && redo_vtable; i++)
/* check method->slot is a valid index: perform isinstance? */
if (method->slot != -1) {
- if (method->klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
+ if (mono_class_is_interface (method->klass)) {
if (!is_proxy) {
gboolean variance_used = FALSE;
int iface_offset = mono_class_interface_offset_with_variance (klass, method->klass, &variance_used);
MonoClass *param_class = klass->cast_class;
- mono_class_setup_fields_locking (klass);
+ mono_class_setup_fields (klass);
g_assert (klass->fields_inited);
g_assert (mono_class_from_mono_type (klass->fields [0].type) == param_class);
mono_error_init (error);
MonoClass *param_class = klass->cast_class;
- mono_class_setup_fields_locking (klass);
+ mono_class_setup_fields (klass);
g_assert (klass->fields_inited);
g_assert (mono_class_from_mono_type (klass->fields [0].type) == param_class);
*pass_size_in_words = FALSE;
- if (mono_class_has_finalizer (vtable->klass) || mono_class_is_marshalbyref (vtable->klass) || (mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS))
+ if (mono_class_has_finalizer (vtable->klass) || mono_class_is_marshalbyref (vtable->klass))
return ves_icall_object_new_specific;
if (vtable->gc_descr != MONO_GC_DESCRIPTOR_NULL) {
o = (MonoObject *)mono_gc_alloc_vector (vtable, byte_len, len);
if (G_UNLIKELY (!o)) {
- mono_error_set_out_of_memory (error, "Could not allocate %i bytes", byte_len);
+ mono_error_set_out_of_memory (error, "Could not allocate %zd bytes", (gsize) byte_len);
return NULL;
}
o = (MonoObject *)mono_gc_alloc_vector (vtable, byte_len, n);
if (G_UNLIKELY (!o)) {
- mono_error_set_out_of_memory (error, "Could not allocate %i bytes", byte_len);
+ mono_error_set_out_of_memory (error, "Could not allocate %zd bytes", (gsize) byte_len);
return NULL;
}
s = (MonoString *)mono_gc_alloc_string (vtable, size, len);
if (G_UNLIKELY (!s)) {
- mono_error_set_out_of_memory (error, "Could not allocate %i bytes", size);
+ mono_error_set_out_of_memory (error, "Could not allocate %zd bytes", size);
return NULL;
}
if (!klass->inited)
mono_class_init (klass);
- if (mono_class_is_marshalbyref (klass) || (klass->flags & TYPE_ATTRIBUTE_INTERFACE)) {
+ if (mono_class_is_marshalbyref (klass) || mono_class_is_interface (klass)) {
result = mono_object_isinst_mbyref_checked (obj, klass, error);
return result;
}
vt = obj->vtable;
- if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
+ if (mono_class_is_interface (klass)) {
if (MONO_VTABLE_IMPLEMENTS_INTERFACE (vt, klass->interface_id)) {
return obj;
}
+ /* casting an array one of the invariant interfaces that must act as such */
+ if (klass->is_array_special_interface) {
+ if (mono_class_is_assignable_from (klass, vt->klass))
+ return obj;
+ }
+
/*If the above check fails we are in the slow path of possibly raising an exception. So it's ok to it this way.*/
- if (mono_class_has_variant_generic_params (klass) && mono_class_is_assignable_from (klass, obj->vtable->klass))
+ else if (mono_class_has_variant_generic_params (klass) && mono_class_is_assignable_from (klass, obj->vtable->klass))
return obj;
} else {
MonoClass *oklass = vt->klass;
return as;
}
+char *
+mono_string_handle_to_utf8 (MonoStringHandle s, MonoError *error)
+{
+ return mono_string_to_utf8_checked (MONO_HANDLE_RAW (s), error);
+}
+
/**
* mono_string_to_utf8_ignore:
* @s: a MonoString
mono_monitor_exit ((MonoObject*) ares);
if (wait_event != NULL)
- SetEvent (wait_event);
+ mono_w32event_set (wait_event);
mono_error_init (&error); //the else branch would leave it in an undefined state
if (ac->cb_method)
+static char *
+get_native_backtrace (MonoException *exc_raw)
+{
+ HANDLE_FUNCTION_ENTER ();
+ MONO_HANDLE_DCL(MonoException, exc);
+ char * trace = mono_exception_handle_get_native_backtrace (exc);
+ HANDLE_FUNCTION_RETURN_VAL (trace);
+}
+
/**
* mono_print_unhandled_exception:
* @exc: The exception
} else {
if (((MonoException*)exc)->native_trace_ips) {
- message = mono_exception_get_native_backtrace ((MonoException*)exc);
+ message = get_native_backtrace ((MonoException*)exc);
free_message = TRUE;
} else {
MonoObject *other_exc = NULL;
MONO_OBJECT_SETREF (delegate, target, target);
}
- delegate->invoke_impl = arch_create_delegate_trampoline (delegate->object.vtable->domain, delegate->object.vtable->klass);
+ delegate->invoke_impl = callbacks.create_delegate_trampoline (delegate->object.vtable->domain, delegate->object.vtable->klass);
if (callbacks.init_delegate)
callbacks.init_delegate (delegate);
return TRUE;
ji = mono_jit_info_table_find (mono_get_root_domain (), (char *)mono_get_addr_from_ftnptr (addr));
if (ji) {
method = mono_jit_info_get_method (ji);
- g_assert (!method->klass->generic_container);
+ g_assert (!mono_class_is_gtd (method->klass));
}
return mono_delegate_ctor_with_method (this_obj, target, addr, method, error);