#include "mono/metadata/metadata-internals.h"
#include "mono/metadata/class-internals.h"
#include <mono/metadata/assembly.h>
-#include <mono/metadata/threadpool.h>
#include <mono/metadata/marshal.h>
#include "mono/metadata/debug-helpers.h"
#include "mono/metadata/marshal.h"
#include <mono/utils/mono-counters.h>
#include <mono/utils/mono-error-internals.h>
#include <mono/utils/mono-memory-model.h>
+#include <mono/utils/checked-build.h>
#include "cominterop.h"
-#ifdef HAVE_BOEHM_GC
-#define NEED_TO_ZERO_PTRFREE 1
-#define ALLOC_PTRFREE(obj,vt,size) do { (obj) = GC_MALLOC_ATOMIC ((size)); (obj)->vtable = (vt); (obj)->synchronisation = NULL;} while (0)
-#define ALLOC_OBJECT(obj,vt,size) do { (obj) = GC_MALLOC ((size)); (obj)->vtable = (vt);} while (0)
-#ifdef HAVE_GC_GCJ_MALLOC
-#define GC_NO_DESCRIPTOR ((gpointer)(0 | GC_DS_LENGTH))
-#define ALLOC_TYPED(dest,size,type) do { (dest) = GC_GCJ_MALLOC ((size),(type)); } while (0)
-#else
-#define GC_NO_DESCRIPTOR (NULL)
-#define ALLOC_TYPED(dest,size,type) do { (dest) = GC_MALLOC ((size)); *(gpointer*)dest = (type);} while (0)
-#endif
-#else
-#ifdef HAVE_SGEN_GC
-#define GC_NO_DESCRIPTOR (NULL)
-#define ALLOC_PTRFREE(obj,vt,size) do { (obj) = mono_gc_alloc_obj (vt, size);} while (0)
-#define ALLOC_OBJECT(obj,vt,size) do { (obj) = mono_gc_alloc_obj (vt, size);} while (0)
-#define ALLOC_TYPED(dest,size,type) do { (dest) = mono_gc_alloc_obj (type, size);} while (0)
-#else
-#define NEED_TO_ZERO_PTRFREE 1
-#define GC_NO_DESCRIPTOR (NULL)
-#define ALLOC_PTRFREE(obj,vt,size) do { (obj) = malloc ((size)); (obj)->vtable = (vt); (obj)->synchronisation = NULL;} while (0)
-#define ALLOC_OBJECT(obj,vt,size) do { (obj) = calloc (1, (size)); (obj)->vtable = (vt);} while (0)
-#define ALLOC_TYPED(dest,size,type) do { (dest) = calloc (1, (size)); *(gpointer*)dest = (type);} while (0)
-#endif
-#endif
-
-static MonoObject* mono_object_new_ptrfree (MonoVTable *vtable);
-static MonoObject* mono_object_new_ptrfree_box (MonoVTable *vtable);
-
static void
get_default_field_value (MonoDomain* domain, MonoClassField *field, void *value);
#define ldstr_unlock() mono_mutex_unlock (&ldstr_section)
static mono_mutex_t ldstr_section;
-static gboolean profile_allocs = TRUE;
-
void
mono_runtime_object_init (MonoObject *this)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoMethod *method = NULL;
MonoClass *klass = this->vtable->klass;
} TypeInitializationLock;
/* for locking access to type_initialization_hash and blocked_thread_hash */
-#define mono_type_initialization_lock() mono_mutex_lock (&type_initialization_section)
-#define mono_type_initialization_unlock() mono_mutex_unlock (&type_initialization_section)
static mono_mutex_t type_initialization_section;
+static inline void
+mono_type_initialization_lock (void)
+{
+ /* The critical sections protected by this lock in mono_runtime_class_init_full () can block */
+ MONO_PREPARE_BLOCKING;
+ mono_mutex_lock (&type_initialization_section);
+ MONO_FINISH_BLOCKING;
+}
+
+static inline void
+mono_type_initialization_unlock (void)
+{
+ mono_mutex_unlock (&type_initialization_section);
+}
static void
mono_type_init_lock (TypeInitializationLock *lock)
{
- MONO_TRY_BLOCKING
+ MONO_REQ_GC_NEUTRAL_MODE;
+
+ MONO_TRY_BLOCKING;
mono_mutex_lock (&lock->initialization_section);
- MONO_FINISH_TRY_BLOCKING
+ MONO_FINISH_TRY_BLOCKING;
}
static void
void
mono_thread_set_main (MonoThread *thread)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static gboolean registered = FALSE;
if (!registered) {
- MONO_GC_REGISTER_ROOT_SINGLE (main_thread);
+ MONO_GC_REGISTER_ROOT_SINGLE (main_thread, MONO_ROOT_SOURCE_THREADING, "main thread object");
registered = TRUE;
}
MonoThread*
mono_thread_get_main (void)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return main_thread;
}
static MonoException*
get_type_init_exception_for_vtable (MonoVTable *vtable)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDomain *domain = vtable->domain;
MonoClass *klass = vtable->klass;
MonoException *ex;
void
mono_runtime_class_init (MonoVTable *vtable)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
mono_runtime_class_init_full (vtable, TRUE);
}
MonoException *
mono_runtime_class_init_full (MonoVTable *vtable, gboolean raise_exception)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoException *exc;
MonoException *exc_to_throw;
MonoMethod *method = NULL;
MonoClass *klass;
gchar *full_name;
+ MonoDomain *domain = vtable->domain;
+ TypeInitializationLock *lock;
+ guint32 tid;
+ int do_initialization = 0;
+ MonoDomain *last_domain = NULL;
if (vtable->initialized)
return NULL;
}
}
method = mono_class_get_cctor (klass);
+ if (!method) {
+ vtable->initialized = 1;
+ return NULL;
+ }
- if (method) {
- MonoDomain *domain = vtable->domain;
- TypeInitializationLock *lock;
- guint32 tid = GetCurrentThreadId();
- int do_initialization = 0;
- MonoDomain *last_domain = NULL;
+ tid = GetCurrentThreadId ();
- mono_type_initialization_lock ();
- /* double check... */
- if (vtable->initialized) {
+ mono_type_initialization_lock ();
+ /* double check... */
+ if (vtable->initialized) {
+ mono_type_initialization_unlock ();
+ return NULL;
+ }
+ if (vtable->init_failed) {
+ mono_type_initialization_unlock ();
+
+ /* The type initialization already failed once, rethrow the same exception */
+ if (raise_exception)
+ mono_raise_exception (get_type_init_exception_for_vtable (vtable));
+ return get_type_init_exception_for_vtable (vtable);
+ }
+ lock = g_hash_table_lookup (type_initialization_hash, vtable);
+ if (lock == NULL) {
+ /* This thread will get to do the initialization */
+ if (mono_domain_get () != domain) {
+ /* Transfer into the target domain */
+ last_domain = mono_domain_get ();
+ if (!mono_domain_set (domain, FALSE)) {
+ vtable->initialized = 1;
+ mono_type_initialization_unlock ();
+ if (raise_exception)
+ mono_raise_exception (mono_get_exception_appdomain_unloaded ());
+ return mono_get_exception_appdomain_unloaded ();
+ }
+ }
+ lock = g_malloc (sizeof(TypeInitializationLock));
+ mono_mutex_init_recursive (&lock->initialization_section);
+ lock->initializing_tid = tid;
+ lock->waiting_count = 1;
+ lock->done = FALSE;
+ /* grab the vtable lock while this thread still owns type_initialization_section */
+ /* This is why type_initialization_lock needs to enter blocking mode */
+ mono_type_init_lock (lock);
+ g_hash_table_insert (type_initialization_hash, vtable, lock);
+ do_initialization = 1;
+ } else {
+ gpointer blocked;
+ TypeInitializationLock *pending_lock;
+
+ if (lock->initializing_tid == tid || lock->done) {
mono_type_initialization_unlock ();
return NULL;
}
- if (vtable->init_failed) {
- mono_type_initialization_unlock ();
-
- /* The type initialization already failed once, rethrow the same exception */
- if (raise_exception)
- mono_raise_exception (get_type_init_exception_for_vtable (vtable));
- return get_type_init_exception_for_vtable (vtable);
- }
- lock = g_hash_table_lookup (type_initialization_hash, vtable);
- if (lock == NULL) {
- /* This thread will get to do the initialization */
- if (mono_domain_get () != domain) {
- /* Transfer into the target domain */
- last_domain = mono_domain_get ();
- if (!mono_domain_set (domain, FALSE)) {
- vtable->initialized = 1;
+ /* see if the thread doing the initialization is already blocked on this thread */
+ blocked = GUINT_TO_POINTER (lock->initializing_tid);
+ while ((pending_lock = (TypeInitializationLock*) g_hash_table_lookup (blocked_thread_hash, blocked))) {
+ if (pending_lock->initializing_tid == tid) {
+ if (!pending_lock->done) {
mono_type_initialization_unlock ();
- if (raise_exception)
- mono_raise_exception (mono_get_exception_appdomain_unloaded ());
- return mono_get_exception_appdomain_unloaded ();
- }
- }
- lock = g_malloc (sizeof(TypeInitializationLock));
- mono_mutex_init_recursive (&lock->initialization_section);
- lock->initializing_tid = tid;
- lock->waiting_count = 1;
- lock->done = FALSE;
- /* grab the vtable lock while this thread still owns type_initialization_section */
- mono_type_init_lock (lock);
- g_hash_table_insert (type_initialization_hash, vtable, lock);
- do_initialization = 1;
- } else {
- gpointer blocked;
- TypeInitializationLock *pending_lock;
-
- if (lock->initializing_tid == tid || lock->done) {
- mono_type_initialization_unlock ();
- return NULL;
- }
- /* see if the thread doing the initialization is already blocked on this thread */
- blocked = GUINT_TO_POINTER (lock->initializing_tid);
- while ((pending_lock = (TypeInitializationLock*) g_hash_table_lookup (blocked_thread_hash, blocked))) {
- if (pending_lock->initializing_tid == tid) {
- if (!pending_lock->done) {
- mono_type_initialization_unlock ();
- return NULL;
- } else {
- /* the thread doing the initialization is blocked on this thread,
- but on a lock that has already been freed. It just hasn't got
- time to awake */
- break;
- }
+ return NULL;
+ } else {
+ /* the thread doing the initialization is blocked on this thread,
+ but on a lock that has already been freed. It just hasn't got
+ time to awake */
+ break;
}
- blocked = GUINT_TO_POINTER (pending_lock->initializing_tid);
}
- ++lock->waiting_count;
- /* record the fact that we are waiting on the initializing thread */
- g_hash_table_insert (blocked_thread_hash, GUINT_TO_POINTER (tid), lock);
+ blocked = GUINT_TO_POINTER (pending_lock->initializing_tid);
}
- mono_type_initialization_unlock ();
-
- if (do_initialization) {
- mono_runtime_invoke (method, NULL, NULL, (MonoObject **) &exc);
+ ++lock->waiting_count;
+ /* record the fact that we are waiting on the initializing thread */
+ g_hash_table_insert (blocked_thread_hash, GUINT_TO_POINTER (tid), lock);
+ }
+ mono_type_initialization_unlock ();
- /* If the initialization failed, mark the class as unusable. */
- /* Avoid infinite loops */
- if (!(exc == NULL ||
- (klass->image == mono_defaults.corlib &&
- !strcmp (klass->name_space, "System") &&
- !strcmp (klass->name, "TypeInitializationException")))) {
- vtable->init_failed = 1;
+ if (do_initialization) {
+ mono_runtime_invoke (method, NULL, NULL, (MonoObject **) &exc);
- if (klass->name_space && *klass->name_space)
- full_name = g_strdup_printf ("%s.%s", klass->name_space, klass->name);
- else
- full_name = g_strdup (klass->name);
- exc_to_throw = mono_get_exception_type_initialization (full_name, exc);
- g_free (full_name);
-
- /*
- * Store the exception object so it could be thrown on subsequent
- * accesses.
- */
- mono_domain_lock (domain);
- if (!domain->type_init_exception_hash)
- domain->type_init_exception_hash = mono_g_hash_table_new_type (mono_aligned_addr_hash, NULL, MONO_HASH_VALUE_GC);
- mono_g_hash_table_insert (domain->type_init_exception_hash, klass, exc_to_throw);
- mono_domain_unlock (domain);
- }
+ /* If the initialization failed, mark the class as unusable. */
+ /* Avoid infinite loops */
+ if (!(exc == NULL ||
+ (klass->image == mono_defaults.corlib &&
+ !strcmp (klass->name_space, "System") &&
+ !strcmp (klass->name, "TypeInitializationException")))) {
+ vtable->init_failed = 1;
- if (last_domain)
- mono_domain_set (last_domain, TRUE);
- lock->done = TRUE;
- mono_type_init_unlock (lock);
- } else {
- /* this just blocks until the initializing thread is done */
- mono_type_init_lock (lock);
- mono_type_init_unlock (lock);
- }
+ if (klass->name_space && *klass->name_space)
+ full_name = g_strdup_printf ("%s.%s", klass->name_space, klass->name);
+ else
+ full_name = g_strdup (klass->name);
+ exc_to_throw = mono_get_exception_type_initialization (full_name, exc);
+ g_free (full_name);
- mono_type_initialization_lock ();
- if (lock->initializing_tid != tid)
- g_hash_table_remove (blocked_thread_hash, GUINT_TO_POINTER (tid));
- --lock->waiting_count;
- if (lock->waiting_count == 0) {
- mono_mutex_destroy (&lock->initialization_section);
- g_hash_table_remove (type_initialization_hash, vtable);
- g_free (lock);
+ /*
+ * Store the exception object so it could be thrown on subsequent
+ * accesses.
+ */
+ mono_domain_lock (domain);
+ if (!domain->type_init_exception_hash)
+ domain->type_init_exception_hash = mono_g_hash_table_new_type (mono_aligned_addr_hash, NULL, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "type initialization exceptions table");
+ mono_g_hash_table_insert (domain->type_init_exception_hash, klass, exc_to_throw);
+ mono_domain_unlock (domain);
}
- mono_memory_barrier ();
- if (!vtable->init_failed)
- vtable->initialized = 1;
- mono_type_initialization_unlock ();
- if (vtable->init_failed) {
- /* Either we were the initializing thread or we waited for the initialization */
- if (raise_exception)
- mono_raise_exception (get_type_init_exception_for_vtable (vtable));
- return get_type_init_exception_for_vtable (vtable);
- }
+ if (last_domain)
+ mono_domain_set (last_domain, TRUE);
+ lock->done = TRUE;
+ mono_type_init_unlock (lock);
} else {
+ /* this just blocks until the initializing thread is done */
+ mono_type_init_lock (lock);
+ mono_type_init_unlock (lock);
+ }
+
+ mono_type_initialization_lock ();
+ if (lock->initializing_tid != tid)
+ g_hash_table_remove (blocked_thread_hash, GUINT_TO_POINTER (tid));
+ --lock->waiting_count;
+ if (lock->waiting_count == 0) {
+ mono_mutex_destroy (&lock->initialization_section);
+ g_hash_table_remove (type_initialization_hash, vtable);
+ g_free (lock);
+ }
+ mono_memory_barrier ();
+ if (!vtable->init_failed)
vtable->initialized = 1;
- return NULL;
+ mono_type_initialization_unlock ();
+
+ if (vtable->init_failed) {
+ /* Either we were the initializing thread or we waited for the initialization */
+ if (raise_exception)
+ mono_raise_exception (get_type_init_exception_for_vtable (vtable));
+ return get_type_init_exception_for_vtable (vtable);
}
return NULL;
}
static
gboolean release_type_locks (gpointer key, gpointer value, gpointer user)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoVTable *vtable = (MonoVTable*)key;
TypeInitializationLock *lock = (TypeInitializationLock*) value;
void
mono_release_type_locks (MonoInternalThread *thread)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
mono_type_initialization_lock ();
g_hash_table_foreach_remove (type_initialization_hash, release_type_locks, (gpointer)(gsize)(thread->tid));
mono_type_initialization_unlock ();
gpointer
mono_compile_method (MonoMethod *method)
{
+ MONO_REQ_GC_NEUTRAL_MODE
+
if (!default_mono_compile_method) {
g_error ("compile method called on uninitialized runtime");
return NULL;
gpointer
mono_runtime_create_jump_trampoline (MonoDomain *domain, MonoMethod *method, gboolean add_sync_wrapper)
{
+ MONO_REQ_GC_NEUTRAL_MODE
+
return arch_create_jump_trampoline (domain, method, add_sync_wrapper);
}
gpointer
mono_runtime_create_delegate_trampoline (MonoClass *klass)
{
+ MONO_REQ_GC_NEUTRAL_MODE
+
return arch_create_delegate_trampoline (mono_domain_get (), klass);
}
void
mono_runtime_free_method (MonoDomain *domain, MonoMethod *method)
{
+ MONO_REQ_GC_NEUTRAL_MODE
+
if (default_mono_free_method != NULL)
default_mono_free_method (domain, method);
static gsize*
compute_class_bitmap (MonoClass *class, gsize *bitmap, int size, int offset, int *max_set, gboolean static_fields)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoClassField *field;
MonoClass *p;
guint32 pos;
if (field->type->byref)
break;
- if (static_fields && field->offset == -1)
- /* special static */
+ // Special static fields do not have a domain-level static slot
+ if (static_fields && mono_class_field_is_special_static (field))
continue;
pos = field->offset / sizeof (gpointer);
gsize*
mono_class_compute_bitmap (MonoClass *class, gsize *bitmap, int size, int offset, int *max_set, gboolean static_fields)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
return compute_class_bitmap (class, bitmap, size, offset, max_set, static_fields);
}
MonoString*
mono_string_alloc (int length)
{
+ MONO_REQ_GC_UNSAFE_MODE;
return mono_string_new_size (mono_domain_get (), length);
}
void
mono_class_compute_gc_descriptor (MonoClass *class)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
int max_set = 0;
gsize *bitmap;
gsize default_bitmap [4] = {0};
if (!gcj_inited) {
mono_loader_lock ();
- mono_register_jit_icall (mono_object_new_ptrfree, "mono_object_new_ptrfree", mono_create_icall_signature ("object ptr"), FALSE);
- mono_register_jit_icall (mono_object_new_ptrfree_box, "mono_object_new_ptrfree_box", mono_create_icall_signature ("object ptr"), FALSE);
mono_register_jit_icall (mono_object_new_fast, "mono_object_new_fast", mono_create_icall_signature ("object ptr"), FALSE);
mono_register_jit_icall (mono_string_alloc, "mono_string_alloc", mono_create_icall_signature ("object int"), FALSE);
-#ifdef HAVE_GC_GCJ_MALLOC
- /*
- * This is not needed unless the relevant code in mono_get_allocation_ftn () is
- * turned on.
- */
-#if 0
-#ifdef GC_REDIRECT_TO_LOCAL
- mono_register_jit_icall (GC_local_gcj_malloc, "GC_local_gcj_malloc", mono_create_icall_signature ("object int ptr"), FALSE);
- mono_register_jit_icall (GC_local_gcj_fast_malloc, "GC_local_gcj_fast_malloc", mono_create_icall_signature ("object int ptr"), FALSE);
-#endif
- mono_register_jit_icall (GC_gcj_malloc, "GC_gcj_malloc", mono_create_icall_signature ("object int ptr"), FALSE);
- mono_register_jit_icall (GC_gcj_fast_malloc, "GC_gcj_fast_malloc", mono_create_icall_signature ("object int ptr"), FALSE);
-#endif
-
-#endif
gcj_inited = TRUE;
mono_loader_unlock ();
}
return;
class->gc_descr_inited = TRUE;
- class->gc_descr = GC_NO_DESCRIPTOR;
+ class->gc_descr = MONO_GC_DESCRIPTOR_NULL;
bitmap = default_bitmap;
if (class == mono_defaults.string_class) {
- class->gc_descr = (gpointer)mono_gc_make_descr_for_string (bitmap, 2);
+ class->gc_descr = mono_gc_make_descr_for_string (bitmap, 2);
} else if (class->rank) {
mono_class_compute_gc_descriptor (class->element_class);
if (MONO_TYPE_IS_REFERENCE (&class->element_class->byval_arg)) {
if (count++ > 58)
return;*/
bitmap = compute_class_bitmap (class, default_bitmap, sizeof (default_bitmap) * 8, 0, &max_set, FALSE);
- class->gc_descr = (gpointer)mono_gc_make_descr_for_object (bitmap, max_set + 1, class->instance_size);
+ class->gc_descr = mono_gc_make_descr_for_object (bitmap, max_set + 1, class->instance_size);
/*
- if (class->gc_descr == GC_NO_DESCRIPTOR)
+ if (class->gc_descr == MONO_GC_DESCRIPTOR_NULL)
g_print ("disabling typed alloc (%d) for %s.%s\n", max_set, class->name_space, class->name);
*/
/*printf ("new descriptor: %p 0x%x for %s.%s\n", class->gc_descr, bitmap [0], class->name_space, class->name);*/
static gint32
field_is_special_static (MonoClass *fklass, MonoClassField *field)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoCustomAttrInfo *ainfo;
int i;
ainfo = mono_custom_attrs_from_field (fklass, field);
guint32
mono_method_get_imt_slot (MonoMethod *method)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoMethodSignature *sig;
int hashes_count;
guint32 *hashes_start, *hashes;
static void
add_imt_builder_entry (MonoImtBuilderEntry **imt_builder, MonoMethod *method, guint32 *imt_collisions_bitmap, int vtable_slot, int slot_num) {
+ MONO_REQ_GC_NEUTRAL_MODE;
+
guint32 imt_slot = mono_method_get_imt_slot (method);
MonoImtBuilderEntry *entry;
static int
imt_emit_ir (MonoImtBuilderEntry **sorted_array, int start, int end, GPtrArray *out_array)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
int count = end - start;
int chunk_start = out_array->len;
if (count < 4) {
static GPtrArray*
imt_sort_slot_entries (MonoImtBuilderEntry *entries) {
+ MONO_REQ_GC_NEUTRAL_MODE;
+
int number_of_entries = entries->children + 1;
MonoImtBuilderEntry **sorted_array = malloc (sizeof (MonoImtBuilderEntry*) * number_of_entries);
GPtrArray *result = g_ptr_array_new ();
static gpointer
initialize_imt_slot (MonoVTable *vtable, MonoDomain *domain, MonoImtBuilderEntry *imt_builder_entry, gpointer fail_tramp)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
if (imt_builder_entry != NULL) {
if (imt_builder_entry->children == 0 && !fail_tramp) {
/* No collision, return the vtable slot contents */
static void
build_imt_slots (MonoClass *klass, MonoVTable *vt, MonoDomain *domain, gpointer* imt, GSList *extra_interfaces, int slot_num)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
int i;
GSList *list_item;
guint32 imt_collisions_bitmap = 0;
static void
build_imt (MonoClass *klass, MonoVTable *vt, MonoDomain *domain, gpointer* imt, GSList *extra_interfaces) {
+ MONO_REQ_GC_NEUTRAL_MODE;
+
build_imt_slots (klass, vt, domain, imt, extra_interfaces, -1);
}
void
mono_vtable_build_imt_slot (MonoVTable* vtable, int imt_slot)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
gpointer *imt = (gpointer*)vtable;
imt -= MONO_IMT_SIZE;
g_assert (imt_slot >= 0 && imt_slot < MONO_IMT_SIZE);
static void
init_thunk_free_lists (MonoDomain *domain)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
if (domain->thunk_free_lists)
return;
domain->thunk_free_lists = mono_domain_alloc0 (domain, sizeof (gpointer) * NUM_FREE_LISTS);
gpointer
mono_method_alloc_generic_virtual_thunk (MonoDomain *domain, int size)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
static gboolean inited = FALSE;
static int generic_virtual_thunks_size = 0;
static void
invalidate_generic_virtual_thunk (MonoDomain *domain, gpointer code)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
guint32 *p = code;
MonoThunkFreeList *l = (MonoThunkFreeList*)(p - 1);
gboolean found = FALSE;
static MonoImtBuilderEntry*
get_generic_virtual_entries (MonoDomain *domain, gpointer *vtable_slot)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
GenericVirtualCase *list;
MonoImtBuilderEntry *entries;
gpointer *vtable_slot,
MonoMethod *method, gpointer code)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
static gboolean inited = FALSE;
static int num_added = 0;
MonoVTable *
mono_class_vtable_full (MonoDomain *domain, MonoClass *class, gboolean raise_on_error)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoClassRuntimeInfo *runtime_info;
g_assert (class);
MonoVTable *
mono_class_try_get_vtable (MonoDomain *domain, MonoClass *class)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoClassRuntimeInfo *runtime_info;
g_assert (class);
static gpointer*
alloc_vtable (MonoDomain *domain, size_t vtable_size, size_t imt_table_bytes)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
size_t alloc_offset;
/*
static MonoVTable *
mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class, gboolean raise_on_error)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoVTable *vt;
MonoClassRuntimeInfo *runtime_info, *old_info;
MonoClassField *field;
*/
#ifdef HAVE_BOEHM_GC
if (domain != mono_get_root_domain () && !mono_dont_free_domains)
- vt->gc_descr = GC_NO_DESCRIPTOR;
+ vt->gc_descr = MONO_GC_DESCRIPTOR_NULL;
else
#endif
vt->gc_descr = class->gc_descr;
if (class_size) {
/* we store the static field pointer at the end of the vtable: vt->vtable [class->vtable_size] */
if (class->has_static_refs) {
- gpointer statics_gc_descr;
+ MonoGCDescriptor statics_gc_descr;
int max_set = 0;
gsize default_bitmap [4] = {0};
gsize *bitmap;
bitmap = compute_class_bitmap (class, default_bitmap, sizeof (default_bitmap) * 8, 0, &max_set, TRUE);
/*g_print ("bitmap 0x%x for %s.%s (size: %d)\n", bitmap [0], class->name_space, class->name, class_size);*/
statics_gc_descr = mono_gc_make_descr_from_bitmap (bitmap, max_set + 1);
- vt->vtable [class->vtable_size] = mono_gc_alloc_fixed (class_size, statics_gc_descr);
+ vt->vtable [class->vtable_size] = mono_gc_alloc_fixed (class_size, statics_gc_descr, MONO_ROOT_SOURCE_STATIC, "managed static variables");
mono_domain_add_class_static_data (domain, class, vt->vtable [class->vtable_size], NULL);
if (bitmap != default_bitmap)
g_free (bitmap);
/* This is unregistered in
unregister_vtable_reflection_type() in
domain.c. */
- MONO_GC_REGISTER_ROOT_IF_MOVING(vt->type);
+ MONO_GC_REGISTER_ROOT_IF_MOVING(vt->type, MONO_ROOT_SOURCE_REFLECTION, "vtable reflection type");
}
mono_vtable_set_is_remote (vt, mono_class_is_contextbound (class));
/* This is unregistered in
unregister_vtable_reflection_type() in
domain.c. */
- MONO_GC_REGISTER_ROOT_IF_MOVING(vt->type);
+ MONO_GC_REGISTER_ROOT_IF_MOVING(vt->type, MONO_ROOT_SOURCE_REFLECTION, "vtable reflection type");
}
mono_domain_unlock (domain);
static MonoVTable *
mono_class_proxy_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, MonoRemotingTarget target_type)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoError error;
MonoVTable *vt, *pvt;
int i, j, vtsize, max_interface_id, extra_interface_vtsize = 0;
gboolean
mono_class_field_is_special_static (MonoClassField *field)
{
+ MONO_REQ_GC_NEUTRAL_MODE
+
if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC))
return FALSE;
if (mono_field_is_deleted (field))
return FALSE;
if (!(field->type->attrs & FIELD_ATTRIBUTE_LITERAL)) {
+ if (field->offset == -1)
+ return TRUE;
if (field_is_special_static (field->parent, field) != SPECIAL_STATIC_NONE)
return TRUE;
}
guint32
mono_class_field_get_special_static_type (MonoClassField *field)
{
+ MONO_REQ_GC_NEUTRAL_MODE
+
if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC))
return SPECIAL_STATIC_NONE;
if (mono_field_is_deleted (field))
gboolean
mono_class_has_special_static_fields (MonoClass *klass)
{
+ MONO_REQ_GC_NEUTRAL_MODE
+
MonoClassField *field;
gpointer iter;
static gpointer*
create_remote_class_key (MonoRemoteClass *remote_class, MonoClass *extra_class)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
gpointer *key;
int i, j;
static gpointer*
copy_remote_class_key (MonoDomain *domain, gpointer *key)
{
+ MONO_REQ_GC_NEUTRAL_MODE
+
int key_size = (GPOINTER_TO_UINT (key [0]) + 1) * sizeof (gpointer);
gpointer *mp_key = mono_domain_alloc (domain, key_size);
MonoRemoteClass*
mono_remote_class (MonoDomain *domain, MonoString *class_name, MonoClass *proxy_class)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoError error;
MonoRemoteClass *rc;
gpointer* key, *mp_key;
static MonoRemoteClass*
clone_remote_class (MonoDomain *domain, MonoRemoteClass* remote_class, MonoClass *extra_class)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoRemoteClass *rc;
gpointer* key, *mp_key;
gpointer
mono_remote_class_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, MonoRealProxy *rp)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
mono_loader_lock (); /*FIXME mono_class_from_mono_type and mono_class_proxy_vtable take it*/
mono_domain_lock (domain);
if (rp->target_domain_id != -1) {
void
mono_upgrade_remote_class (MonoDomain *domain, MonoObject *proxy_object, MonoClass *klass)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoTransparentProxy *tproxy;
MonoRemoteClass *remote_class;
gboolean redo_vtable;
MonoMethod*
mono_object_get_virtual_method (MonoObject *obj, MonoMethod *method)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoClass *klass;
MonoMethod **vtable;
gboolean is_proxy = FALSE;
MonoObject*
mono_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoObject *result;
if (mono_runtime_get_no_exec ())
gpointer
mono_method_get_unmanaged_thunk (MonoMethod *method)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+ MONO_REQ_API_ENTRYPOINT;
+
+ gpointer res;
+
+ MONO_PREPARE_RESET_BLOCKING
method = mono_marshal_get_thunk_invoke_wrapper (method);
- return mono_compile_method (method);
+ res = mono_compile_method (method);
+ MONO_FINISH_RESET_BLOCKING
+
+ return res;
}
void
mono_copy_value (MonoType *type, void *dest, void *value, int deref_pointer)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
int t;
if (type->byref) {
/* object fields cannot be byref, so we don't need a
void
mono_field_set_value (MonoObject *obj, MonoClassField *field, void *value)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
void *dest;
g_return_if_fail (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC));
void
mono_field_static_set_value (MonoVTable *vt, MonoClassField *field, void *value)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
void *dest;
g_return_if_fail (field->type->attrs & FIELD_ATTRIBUTE_STATIC);
void *
mono_vtable_get_static_field_data (MonoVTable *vt)
{
+ MONO_REQ_GC_NEUTRAL_MODE
+
if (!vt->has_static_fields)
return NULL;
return vt->vtable [vt->klass->vtable_size];
static guint8*
mono_field_get_addr (MonoObject *obj, MonoVTable *vt, MonoClassField *field)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
guint8 *src;
if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
void
mono_field_get_value (MonoObject *obj, MonoClassField *field, void *value)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
void *src;
g_assert (obj);
MonoObject *
mono_field_get_value_object (MonoDomain *domain, MonoClassField *field, MonoObject *obj)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoObject *o;
MonoClass *klass;
MonoVTable *vtable = NULL;
int
mono_get_constant_value_from_blob (MonoDomain* domain, MonoTypeEnum type, const char *blob, void *value)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
int retval = 0;
const char *p = blob;
mono_metadata_decode_blob_size (p, &p);
static void
get_default_field_value (MonoDomain* domain, MonoClassField *field, void *value)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoTypeEnum def_type;
const char* data;
void
mono_field_static_get_value_for_thread (MonoInternalThread *thread, MonoVTable *vt, MonoClassField *field, void *value)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
void *src;
g_return_if_fail (field->type->attrs & FIELD_ATTRIBUTE_STATIC);
void
mono_field_static_get_value (MonoVTable *vt, MonoClassField *field, void *value)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
mono_field_static_get_value_for_thread (mono_thread_internal_current (), vt, field, value);
}
void
mono_property_set_value (MonoProperty *prop, void *obj, void **params, MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
default_mono_runtime_invoke (prop->set, obj, params, exc);
}
MonoObject*
mono_property_get_value (MonoProperty *prop, void *obj, void **params, MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return default_mono_runtime_invoke (prop->get, obj, params, exc);
}
void
mono_nullable_init (guint8 *buf, MonoObject *value, MonoClass *klass)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoClass *param_class = klass->cast_class;
mono_class_setup_fields_locking (klass);
MonoObject*
mono_nullable_box (guint8 *buf, MonoClass *klass)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoClass *param_class = klass->cast_class;
mono_class_setup_fields_locking (klass);
MonoMethod *
mono_get_delegate_invoke (MonoClass *klass)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoMethod *im;
/* This is called at runtime, so avoid the slower search in metadata */
MonoMethod *
mono_get_delegate_begin_invoke (MonoClass *klass)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoMethod *im;
/* This is called at runtime, so avoid the slower search in metadata */
MonoMethod *
mono_get_delegate_end_invoke (MonoClass *klass)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoMethod *im;
/* This is called at runtime, so avoid the slower search in metadata */
MonoObject*
mono_runtime_delegate_invoke (MonoObject *delegate, void **params, MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoMethod *im;
MonoClass *klass = delegate->vtable->klass;
MonoArray*
mono_runtime_get_main_args (void)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoArray *res;
int i;
MonoDomain *domain = mono_domain_get ();
static void
free_main_args (void)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
int i;
for (i = 0; i < num_main_args; ++i)
int
mono_runtime_set_main_args (int argc, char* argv[])
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
int i;
free_main_args ();
mono_runtime_run_main (MonoMethod *method, int argc, char* argv[],
MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
int i;
MonoArray *args = NULL;
MonoDomain *domain = mono_domain_get ();
static MonoObject*
deserialize_object (MonoObject *obj, gboolean *failure, MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static MonoMethod *deserialize_method;
void *params [1];
static MonoObject*
make_transparent_proxy (MonoObject *obj, gboolean *failure, MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static MonoMethod *get_proxy_method;
MonoDomain *domain = mono_domain_get ();
MonoObject*
mono_object_xdomain_representation (MonoObject *obj, MonoDomain *target_domain, MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoObject *deserialized = NULL;
gboolean failure = FALSE;
static MonoObject *
create_unhandled_exception_eventargs (MonoObject *exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoClass *klass;
gpointer args [2];
MonoMethod *method = NULL;
/* Used in mono_unhandled_exception */
static void
call_unhandled_exception_delegate (MonoDomain *domain, MonoObject *delegate, MonoObject *exc) {
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoObject *e = NULL;
gpointer pa [2];
MonoDomain *current_domain = mono_domain_get ();
void
mono_unhandled_exception (MonoObject *exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDomain *current_domain = mono_domain_get ();
MonoDomain *root_domain = mono_get_root_domain ();
MonoClassField *field;
int
mono_runtime_exec_main (MonoMethod *method, MonoArray *args, MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDomain *domain;
gpointer pa [1];
int rval;
mono_runtime_invoke_array (MonoMethod *method, void *obj, MonoArray *params,
MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoMethodSignature *sig = mono_method_signature (method);
gpointer *pa = NULL;
MonoObject *res;
static void
arith_overflow (void)
{
- mono_raise_exception (mono_get_exception_overflow ());
-}
-
-/**
- * mono_object_allocate:
- * @size: number of bytes to allocate
- *
- * This is a very simplistic routine until we have our GC-aware
- * memory allocator.
- *
- * Returns: an allocated object of size @size, or NULL on failure.
- */
-static inline void *
-mono_object_allocate (size_t size, MonoVTable *vtable)
-{
- MonoObject *o;
- ALLOC_OBJECT (o, vtable, size);
+ MONO_REQ_GC_UNSAFE_MODE;
- return o;
-}
-
-#ifndef HAVE_SGEN_GC
-/**
- * mono_object_allocate_ptrfree:
- * @size: number of bytes to allocate
- *
- * Note that the memory allocated is not zeroed.
- * Returns: an allocated object of size @size, or NULL on failure.
- */
-static inline void *
-mono_object_allocate_ptrfree (size_t size, MonoVTable *vtable)
-{
- MonoObject *o;
- ALLOC_PTRFREE (o, vtable, size);
- return o;
-}
-#endif
-
-static inline void *
-mono_object_allocate_spec (size_t size, MonoVTable *vtable)
-{
- void *o;
- ALLOC_TYPED (o, size, vtable);
-
- return o;
+ mono_raise_exception (mono_get_exception_overflow ());
}
/**
MonoObject *
mono_object_new (MonoDomain *domain, MonoClass *klass)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoVTable *vtable;
vtable = mono_class_vtable (domain, klass);
MonoObject *
mono_object_new_pinned (MonoDomain *domain, MonoClass *klass)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoVTable *vtable;
vtable = mono_class_vtable (domain, klass);
MonoObject *
mono_object_new_specific (MonoVTable *vtable)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoObject *o;
/* check for is_com_object for COM Interop */
mono_class_init (klass);
im = mono_class_get_method_from_name (klass, "CreateProxyForType", 1);
- g_assert (im);
+ if (!im)
+ mono_raise_exception (mono_get_exception_not_supported ("Linked away."));
vtable->domain->create_proxy_for_type_method = im;
}
MonoObject *
mono_object_new_alloc_specific (MonoVTable *vtable)
{
- MonoObject *o;
+ MONO_REQ_GC_UNSAFE_MODE;
+
+ MonoObject *o = mono_gc_alloc_obj (vtable, vtable->klass->instance_size);
- if (!vtable->klass->has_references) {
- o = mono_object_new_ptrfree (vtable);
- } else if (vtable->gc_descr != GC_NO_DESCRIPTOR) {
- o = mono_object_allocate_spec (vtable->klass->instance_size, vtable);
- } else {
-/* printf("OBJECT: %s.%s.\n", vtable->klass->name_space, vtable->klass->name); */
- o = mono_object_allocate (vtable->klass->instance_size, vtable);
- }
if (G_UNLIKELY (vtable->klass->has_finalize))
mono_object_register_finalizer (o);
-
- if (G_UNLIKELY (profile_allocs))
- mono_profiler_allocation (o, vtable->klass);
+
return o;
}
MonoObject*
mono_object_new_fast (MonoVTable *vtable)
{
- MonoObject *o;
- ALLOC_TYPED (o, vtable->klass->instance_size, vtable);
- return o;
-}
-
-static MonoObject*
-mono_object_new_ptrfree (MonoVTable *vtable)
-{
- MonoObject *obj;
- ALLOC_PTRFREE (obj, vtable, vtable->klass->instance_size);
-#if NEED_TO_ZERO_PTRFREE
- /* an inline memset is much faster for the common vcase of small objects
- * note we assume the allocated size is a multiple of sizeof (void*).
- */
- if (vtable->klass->instance_size < 128) {
- gpointer *p, *end;
- end = (gpointer*)((char*)obj + vtable->klass->instance_size);
- p = (gpointer*)((char*)obj + sizeof (MonoObject));
- while (p < end) {
- *p = NULL;
- ++p;
- }
- } else {
- memset ((char*)obj + sizeof (MonoObject), 0, vtable->klass->instance_size - sizeof (MonoObject));
- }
-#endif
- return obj;
-}
+ MONO_REQ_GC_UNSAFE_MODE;
-static MonoObject*
-mono_object_new_ptrfree_box (MonoVTable *vtable)
-{
- MonoObject *obj;
- ALLOC_PTRFREE (obj, vtable, vtable->klass->instance_size);
- /* the object will be boxed right away, no need to memzero it */
- return obj;
+ return mono_gc_alloc_obj (vtable, vtable->klass->instance_size);
}
/**
void*
mono_class_get_allocation_ftn (MonoVTable *vtable, gboolean for_box, gboolean *pass_size_in_words)
{
- *pass_size_in_words = FALSE;
+ MONO_REQ_GC_NEUTRAL_MODE;
- if (!(mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS))
- profile_allocs = FALSE;
+ *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))
return mono_object_new_specific;
- if (!vtable->klass->has_references) {
- //g_print ("ptrfree for %s.%s\n", vtable->klass->name_space, vtable->klass->name);
- if (for_box)
- return mono_object_new_ptrfree_box;
- return mono_object_new_ptrfree;
- }
-
- if (vtable->gc_descr != GC_NO_DESCRIPTOR) {
+ if (vtable->gc_descr != MONO_GC_DESCRIPTOR_NULL) {
return mono_object_new_fast;
MonoObject *
mono_object_new_from_token (MonoDomain *domain, MonoImage *image, guint32 token)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoError error;
MonoClass *class;
MonoObject *
mono_object_clone (MonoObject *obj)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoObject *o;
int size = obj->vtable->klass->instance_size;
if (obj->vtable->klass->rank)
return (MonoObject*)mono_array_clone ((MonoArray*)obj);
- o = mono_object_allocate (size, obj->vtable);
+ o = mono_gc_alloc_obj (obj->vtable, size);
/* If the object doesn't contain references this will do a simple memmove. */
mono_gc_wbarrier_object_copy (o, obj);
- if (G_UNLIKELY (profile_allocs))
- mono_profiler_allocation (o, obj->vtable->klass);
-
if (obj->vtable->klass->has_finalize)
mono_object_register_finalizer (o);
return o;
void
mono_array_full_copy (MonoArray *src, MonoArray *dest)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
uintptr_t size;
MonoClass *klass = src->obj.vtable->klass;
MonoArray*
mono_array_clone_in_domain (MonoDomain *domain, MonoArray *array)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoArray *o;
uintptr_t size, i;
uintptr_t *sizes;
MonoArray*
mono_array_clone (MonoArray *array)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return mono_array_clone_in_domain (((MonoObject *)array)->vtable->domain, array);
}
gboolean
mono_array_calc_byte_len (MonoClass *class, uintptr_t len, uintptr_t *res)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
uintptr_t byte_len;
byte_len = mono_array_element_size (class);
MonoArray*
mono_array_new_full (MonoDomain *domain, MonoClass *array_class, uintptr_t *lengths, intptr_t *lower_bounds)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
uintptr_t byte_len = 0, len, bounds_size;
MonoObject *o;
MonoArray *array;
* they need to be kept in sync.
*/
vtable = mono_class_vtable_full (domain, array_class, TRUE);
-#ifndef HAVE_SGEN_GC
- if (!array_class->has_references) {
- o = mono_object_allocate_ptrfree (byte_len, vtable);
-#if NEED_TO_ZERO_PTRFREE
- memset ((char*)o + sizeof (MonoObject), 0, byte_len - sizeof (MonoObject));
-#endif
- } else if (vtable->gc_descr != GC_NO_DESCRIPTOR) {
- o = mono_object_allocate_spec (byte_len, vtable);
- }else {
- o = mono_object_allocate (byte_len, vtable);
- }
-
- array = (MonoArray*)o;
- array->max_length = len;
-
- if (bounds_size) {
- bounds = (MonoArrayBounds*)((char*)array + byte_len - bounds_size);
- array->bounds = bounds;
- }
-#else
if (bounds_size)
o = mono_gc_alloc_array (vtable, byte_len, len, bounds_size);
else
array = (MonoArray*)o;
bounds = array->bounds;
-#endif
if (bounds_size) {
for (i = 0; i < array_class->rank; ++i) {
}
}
- if (G_UNLIKELY (profile_allocs))
- mono_profiler_allocation (o, array_class);
-
return array;
}
MonoArray *
mono_array_new (MonoDomain *domain, MonoClass *eclass, uintptr_t n)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoClass *ac;
ac = mono_array_class_get (eclass, 1);
MonoArray *
mono_array_new_specific (MonoVTable *vtable, uintptr_t n)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoObject *o;
MonoArray *ao;
uintptr_t byte_len;
mono_gc_out_of_memory (MONO_ARRAY_MAX_SIZE);
return NULL;
}
-#ifndef HAVE_SGEN_GC
- if (!vtable->klass->has_references) {
- o = mono_object_allocate_ptrfree (byte_len, vtable);
-#if NEED_TO_ZERO_PTRFREE
- ((MonoArray*)o)->bounds = NULL;
- memset ((char*)o + sizeof (MonoObject), 0, byte_len - sizeof (MonoObject));
-#endif
- } else if (vtable->gc_descr != GC_NO_DESCRIPTOR) {
- o = mono_object_allocate_spec (byte_len, vtable);
- } else {
-/* printf("ARRAY: %s.%s.\n", vtable->klass->name_space, vtable->klass->name); */
- o = mono_object_allocate (byte_len, vtable);
- }
-
- ao = (MonoArray *)o;
- ao->max_length = n;
-#else
o = mono_gc_alloc_vector (vtable, byte_len, n);
ao = (MonoArray*)o;
-#endif
-
- if (G_UNLIKELY (profile_allocs))
- mono_profiler_allocation (o, vtable->klass);
return ao;
}
MonoString *
mono_string_new_utf16 (MonoDomain *domain, const guint16 *text, gint32 len)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoString *s;
s = mono_string_new_size (domain, len);
MonoString *
mono_string_new_utf32 (MonoDomain *domain, const mono_unichar4 *text, gint32 len)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoString *s;
mono_unichar2 *utf16_output = NULL;
gint32 utf16_len = 0;
MonoString *
mono_string_new_size (MonoDomain *domain, gint32 len)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoString *s;
MonoVTable *vtable;
size_t size;
vtable = mono_class_vtable (domain, mono_defaults.string_class);
g_assert (vtable);
-#ifndef HAVE_SGEN_GC
- s = mono_object_allocate_ptrfree (size, vtable);
-
- s->length = len;
-#else
s = mono_gc_alloc_string (vtable, size, len);
-#endif
-#if NEED_TO_ZERO_PTRFREE
- s->chars [len] = 0;
-#endif
- if (G_UNLIKELY (profile_allocs))
- mono_profiler_allocation ((MonoObject*)s, mono_defaults.string_class);
return s;
}
MonoString*
mono_string_new_len (MonoDomain *domain, const char *text, guint length)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
GError *error = NULL;
MonoString *o = NULL;
guint16 *ut;
MonoString*
mono_string_new (MonoDomain *domain, const char *text)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
GError *error = NULL;
MonoString *o = NULL;
guint16 *ut;
MonoString*
mono_string_new_wrapper (const char *text)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDomain *domain = mono_domain_get ();
if (text)
MonoObject *
mono_value_box (MonoDomain *domain, MonoClass *class, gpointer value)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoObject *res;
int size;
MonoVTable *vtable;
return NULL;
size = mono_class_instance_size (class);
res = mono_object_new_alloc_specific (vtable);
- if (G_UNLIKELY (profile_allocs))
- mono_profiler_allocation (res, class);
size = size - sizeof (MonoObject);
void
mono_value_copy (gpointer dest, gpointer src, MonoClass *klass)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
mono_gc_wbarrier_value_copy (dest, src, 1, klass);
}
void
mono_value_copy_array (MonoArray *dest, int dest_idx, gpointer src, int count)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
int size = mono_array_element_size (dest->obj.vtable->klass);
char *d = mono_array_addr_with_size_fast (dest, size, dest_idx);
g_assert (size == mono_class_value_size (mono_object_class (dest)->element_class, NULL));
MonoDomain*
mono_object_get_domain (MonoObject *obj)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return mono_object_domain (obj);
}
MonoClass*
mono_object_get_class (MonoObject *obj)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return mono_object_class (obj);
}
/**
guint
mono_object_get_size (MonoObject* o)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoClass* klass = mono_object_class (o);
if (klass == mono_defaults.string_class) {
return sizeof (MonoString) + 2 * mono_string_length ((MonoString*) o) + 2;
gpointer
mono_object_unbox (MonoObject *obj)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
/* add assert for valuetypes? */
g_assert (obj->vtable->klass->valuetype);
return ((char*)obj) + sizeof (MonoObject);
MonoObject *
mono_object_isinst (MonoObject *obj, MonoClass *klass)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
if (!klass->inited)
mono_class_init (klass);
MonoObject *
mono_object_isinst_mbyref (MonoObject *obj, MonoClass *klass)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoVTable *vt;
if (!obj)
gpointer pa [2];
im = mono_class_get_method_from_name (rpklass, "CanCastTo", -1);
+ if (!im)
+ mono_raise_exception (mono_get_exception_not_supported ("Linked away."));
im = mono_object_get_virtual_method (rp, im);
g_assert (im);
MonoObject *
mono_object_castclass_mbyref (MonoObject *obj, MonoClass *klass)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
if (!obj) return NULL;
if (mono_object_isinst_mbyref (obj, klass)) return obj;
static void
str_lookup (MonoDomain *domain, gpointer user_data)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
LDStrInfo *info = user_data;
if (info->res || domain == info->orig_domain)
return;
static MonoString*
mono_string_get_pinned (MonoString *str)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
int size;
MonoString *news;
size = sizeof (MonoString) + 2 * (mono_string_length (str) + 1);
static MonoString*
mono_string_is_interned_lookup (MonoString *str, int insert)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoGHashTable *ldstr_table;
MonoString *s, *res;
MonoDomain *domain;
MonoString*
mono_string_is_interned (MonoString *o)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return mono_string_is_interned_lookup (o, FALSE);
}
MonoString*
mono_string_intern (MonoString *str)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return mono_string_is_interned_lookup (str, TRUE);
}
MonoString*
mono_ldstr (MonoDomain *domain, MonoImage *image, guint32 idx)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
if (image->dynamic) {
MonoString *str = mono_lookup_dynamic_token (image, MONO_TOKEN_STRING | idx, NULL);
return str;
static MonoString*
mono_ldstr_metadata_sig (MonoDomain *domain, const char* sig)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
const char *str = sig;
MonoString *o, *interned;
size_t len2;
char *
mono_string_to_utf8 (MonoString *s)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoError error;
char *result = mono_string_to_utf8_checked (s, &error);
char *
mono_string_to_utf8_checked (MonoString *s, MonoError *error)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
long written = 0;
char *as;
GError *gerror = NULL;
char *
mono_string_to_utf8_ignore (MonoString *s)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
long written = 0;
char *as;
char *
mono_string_to_utf8_image_ignore (MonoImage *image, MonoString *s)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return mono_string_to_utf8_internal (NULL, image, s, TRUE, NULL);
}
char *
mono_string_to_utf8_mp_ignore (MonoMemPool *mp, MonoString *s)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return mono_string_to_utf8_internal (mp, NULL, s, TRUE, NULL);
}
mono_unichar2*
mono_string_to_utf16 (MonoString *s)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
char *as;
if (s == NULL)
mono_unichar4*
mono_string_to_utf32 (MonoString *s)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
mono_unichar4 *utf32_output = NULL;
GError *error = NULL;
glong items_written;
MonoString *
mono_string_from_utf16 (gunichar2 *data)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDomain *domain = mono_domain_get ();
int len = 0;
MonoString *
mono_string_from_utf32 (mono_unichar4 *data)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoString* result = NULL;
mono_unichar2 *utf16_output = NULL;
GError *error = NULL;
static char *
mono_string_to_utf8_internal (MonoMemPool *mp, MonoImage *image, MonoString *s, gboolean ignore_error, MonoError *error)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
char *r;
char *mp_s;
int len;
char *
mono_string_to_utf8_image (MonoImage *image, MonoString *s, MonoError *error)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return mono_string_to_utf8_internal (NULL, image, s, FALSE, error);
}
char *
mono_string_to_utf8_mp (MonoMemPool *mp, MonoString *s, MonoError *error)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return mono_string_to_utf8_internal (mp, NULL, s, FALSE, error);
}
void
mono_raise_exception (MonoException *ex)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
/*
* NOTE: Do NOT annotate this function with G_GNUC_NORETURN, since
* that will cause gcc to omit the function epilog, causing problems when
void
mono_raise_exception_with_context (MonoException *ex, MonoContext *ctx)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
eh_callbacks.mono_raise_exception_with_ctx (ex, ctx);
}
MonoWaitHandle *
mono_wait_handle_new (MonoDomain *domain, HANDLE handle)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoWaitHandle *res;
gpointer params [1];
static MonoMethod *handle_set;
HANDLE
mono_wait_handle_get_handle (MonoWaitHandle *handle)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static MonoClassField *f_os_handle;
static MonoClassField *f_safe_handle;
static MonoObject*
mono_runtime_capture_context (MonoDomain *domain)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
RuntimeInvokeFunction runtime_invoke;
if (!domain->capture_context_runtime_invoke || !domain->capture_context_method) {
MonoAsyncResult *
mono_async_result_new (MonoDomain *domain, HANDLE handle, MonoObject *state, gpointer data, MonoObject *object_data)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoAsyncResult *res = (MonoAsyncResult *)mono_object_new (domain, mono_defaults.asyncresult_class);
MonoObject *context = mono_runtime_capture_context (domain);
/* we must capture the execution context from the original thread */
}
MonoObject *
-mono_async_result_invoke (MonoAsyncResult *ares, MonoObject **exc)
+ves_icall_System_Runtime_Remoting_Messaging_AsyncResult_Invoke (MonoAsyncResult *ares)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoAsyncCall *ac;
MonoObject *res;
- MonoInternalThread *thread;
g_assert (ares);
g_assert (ares->async_delegate);
- thread = mono_thread_internal_current ();
-
- if (!ares->execution_context) {
- ares->original_context = NULL;
- } else {
- /* use captured ExecutionContext (if available) */
- MONO_OBJECT_SETREF (ares, original_context, mono_thread_get_execution_context ());
- mono_thread_set_execution_context (ares->execution_context);
- }
-
ac = (MonoAsyncCall*) ares->object_data;
if (!ac) {
- thread->async_invoke_method = ((MonoDelegate*) ares->async_delegate)->method;
- res = mono_runtime_delegate_invoke (ares->async_delegate, (void**) &ares->async_state, exc);
- thread->async_invoke_method = NULL;
+ res = mono_runtime_delegate_invoke (ares->async_delegate, (void**) &ares->async_state, NULL);
} else {
- MonoArray *out_args = NULL;
gpointer wait_event = NULL;
ac->msg->exc = NULL;
- res = mono_message_invoke (ares->async_delegate, ac->msg, exc, &out_args);
- MONO_OBJECT_SETREF (ac->msg, exc, *exc);
+ res = mono_message_invoke (ares->async_delegate, ac->msg, &ac->msg->exc, &ac->out_args);
MONO_OBJECT_SETREF (ac, res, res);
- MONO_OBJECT_SETREF (ac, out_args, out_args);
mono_monitor_enter ((MonoObject*) ares);
ares->completed = 1;
if (wait_event != NULL)
SetEvent (wait_event);
- if (!ac->cb_method) {
- *exc = NULL;
- } else {
- thread->async_invoke_method = ac->cb_method;
- mono_runtime_invoke (ac->cb_method, ac->cb_target, (gpointer*) &ares, exc);
- thread->async_invoke_method = NULL;
+ if (ac->cb_method) {
+ /* we swallow the excepton as it is the behavior on .NET */
+ MonoObject *exc = NULL;
+ mono_runtime_invoke (ac->cb_method, ac->cb_target, (gpointer*) &ares, &exc);
+ if (exc)
+ mono_unhandled_exception (exc);
}
}
- /* restore original thread execution context if flow isn't suppressed, i.e. non null */
- if (ares->original_context) {
- mono_thread_set_execution_context (ares->original_context);
- ares->original_context = NULL;
- }
-
- return res;
-}
-
-MonoObject *
-ves_icall_System_Runtime_Remoting_Messaging_AsyncResult_Invoke (MonoAsyncResult *this)
-{
- MonoObject *exc = NULL;
- MonoObject *res = mono_async_result_invoke (this, &exc);
- if (exc)
- mono_raise_exception ((MonoException*) exc);
return res;
}
void
mono_message_init (MonoDomain *domain,
- MonoMethodMessage *this,
+ MonoMethodMessage *this_obj,
MonoReflectionMethod *method,
MonoArray *out_args)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static MonoClass *object_array_klass;
static MonoClass *byte_array_klass;
static MonoClass *string_array_klass;
mono_atomic_store_release (&object_array_klass, klass);
}
- MONO_OBJECT_SETREF (this, method, method);
+ MONO_OBJECT_SETREF (this_obj, method, method);
- MONO_OBJECT_SETREF (this, args, mono_array_new_specific (mono_class_vtable (domain, object_array_klass), sig->param_count));
- MONO_OBJECT_SETREF (this, arg_types, mono_array_new_specific (mono_class_vtable (domain, byte_array_klass), sig->param_count));
- this->async_result = NULL;
- this->call_type = CallType_Sync;
+ MONO_OBJECT_SETREF (this_obj, args, mono_array_new_specific (mono_class_vtable (domain, object_array_klass), sig->param_count));
+ MONO_OBJECT_SETREF (this_obj, arg_types, mono_array_new_specific (mono_class_vtable (domain, byte_array_klass), sig->param_count));
+ this_obj->async_result = NULL;
+ this_obj->call_type = CallType_Sync;
names = g_new (char *, sig->param_count);
mono_method_get_param_names (method->method, (const char **) names);
- MONO_OBJECT_SETREF (this, names, mono_array_new_specific (mono_class_vtable (domain, string_array_klass), sig->param_count));
+ MONO_OBJECT_SETREF (this_obj, names, mono_array_new_specific (mono_class_vtable (domain, string_array_klass), sig->param_count));
for (i = 0; i < sig->param_count; i++) {
name = mono_string_new (domain, names [i]);
- mono_array_setref (this->names, i, name);
+ mono_array_setref (this_obj->names, i, name);
}
g_free (names);
if (sig->params [i]->byref) {
if (out_args) {
MonoObject* arg = mono_array_get (out_args, gpointer, j);
- mono_array_setref (this->args, i, arg);
+ mono_array_setref (this_obj->args, i, arg);
j++;
}
arg_type = 2;
if (sig->params [i]->attrs & PARAM_ATTRIBUTE_OUT)
arg_type |= 4;
}
- mono_array_set (this->arg_types, guint8, i, arg_type);
+ mono_array_set (this_obj->arg_types, guint8, i, arg_type);
}
}
mono_remoting_invoke (MonoObject *real_proxy, MonoMethodMessage *msg,
MonoObject **exc, MonoArray **out_args)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoMethod *im = real_proxy->vtable->domain->private_invoke_method;
gpointer pa [4];
if (!im) {
im = mono_class_get_method_from_name (mono_defaults.real_proxy_class, "PrivateInvoke", 4);
- g_assert (im);
+ if (!im)
+ mono_raise_exception (mono_get_exception_not_supported ("Linked away."));
real_proxy->vtable->domain->private_invoke_method = im;
}
mono_message_invoke (MonoObject *target, MonoMethodMessage *msg,
MonoObject **exc, MonoArray **out_args)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static MonoClass *object_array_klass;
MonoDomain *domain;
MonoMethod *method;
object_array_klass = klass;
}
- /* FIXME: GC ensure we insert a write barrier for out_args, maybe in the caller? */
- *out_args = mono_array_new_specific (mono_class_vtable (domain, object_array_klass), outarg_count);
+ mono_gc_wbarrier_generic_store (out_args, (MonoObject*) mono_array_new_specific (mono_class_vtable (domain, object_array_klass), outarg_count));
*exc = NULL;
ret = mono_runtime_invoke_array (method, method->klass->valuetype? mono_object_unbox (target): target, msg->args, exc);
MonoString *
mono_object_to_string (MonoObject *obj, MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static MonoMethod *to_string = NULL;
MonoMethod *method;
void *target = obj;
void
mono_print_unhandled_exception (MonoObject *exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoString * str;
char *message = (char*)"";
gboolean free_message = FALSE;
* correct instantiation of the method.
*/
void
-mono_delegate_ctor_with_method (MonoObject *this, MonoObject *target, gpointer addr, MonoMethod *method)
+mono_delegate_ctor_with_method (MonoObject *this_obj, MonoObject *target, gpointer addr, MonoMethod *method)
{
- MonoDelegate *delegate = (MonoDelegate *)this;
+ MONO_REQ_GC_UNSAFE_MODE;
+
+ MonoDelegate *delegate = (MonoDelegate *)this_obj;
- g_assert (this);
+ g_assert (this_obj);
g_assert (addr);
- g_assert (mono_class_has_parent (mono_object_class (this), mono_defaults.multicastdelegate_class));
+ g_assert (mono_class_has_parent (mono_object_class (this_obj), mono_defaults.multicastdelegate_class));
if (method)
delegate->method = method;
* This is used to initialize a delegate.
*/
void
-mono_delegate_ctor (MonoObject *this, MonoObject *target, gpointer addr)
+mono_delegate_ctor (MonoObject *this_obj, MonoObject *target, gpointer addr)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDomain *domain = mono_domain_get ();
MonoJitInfo *ji;
MonoMethod *method = NULL;
g_assert (!method->klass->generic_container);
}
- mono_delegate_ctor_with_method (this, target, addr, method);
+ mono_delegate_ctor_with_method (this_obj, target, addr, method);
}
/**
mono_method_call_message_new (MonoMethod *method, gpointer *params, MonoMethod *invoke,
MonoDelegate **cb, MonoObject **state)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDomain *domain = mono_domain_get ();
MonoMethodSignature *sig = mono_method_signature (method);
MonoMethodMessage *msg;
void
mono_method_return_message_restore (MonoMethod *method, gpointer *params, MonoArray *out_args)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoMethodSignature *sig = mono_method_signature (method);
int i, j, type, size, out_len;
* Returns: an address pointing to the value of field.
*/
gpointer
-mono_load_remote_field (MonoObject *this, MonoClass *klass, MonoClassField *field, gpointer *res)
+mono_load_remote_field (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, gpointer *res)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static MonoMethod *getter = NULL;
MonoDomain *domain = mono_domain_get ();
- MonoTransparentProxy *tp = (MonoTransparentProxy *) this;
+ MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
MonoClass *field_class;
MonoMethodMessage *msg;
MonoArray *out_args;
MonoObject *exc;
char* full_name;
- g_assert (mono_object_is_transparent_proxy (this));
+ g_assert (mono_object_is_transparent_proxy (this_obj));
g_assert (res != NULL);
if (mono_class_is_contextbound (tp->remote_class->proxy_class) && tp->rp->context == (MonoObject *) mono_context_get ()) {
if (!getter) {
getter = mono_class_get_method_from_name (mono_defaults.object_class, "FieldGetter", -1);
- g_assert (getter);
+ if (!getter)
+ mono_raise_exception (mono_get_exception_not_supported ("Linked away."));
}
field_class = mono_class_from_mono_type (field->type);
* Missing documentation.
*/
MonoObject *
-mono_load_remote_field_new (MonoObject *this, MonoClass *klass, MonoClassField *field)
+mono_load_remote_field_new (MonoObject *this_obj, MonoClass *klass, MonoClassField *field)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static MonoMethod *getter = NULL;
MonoDomain *domain = mono_domain_get ();
- MonoTransparentProxy *tp = (MonoTransparentProxy *) this;
+ MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
MonoClass *field_class;
MonoMethodMessage *msg;
MonoArray *out_args;
MonoObject *exc, *res;
char* full_name;
- g_assert (mono_object_is_transparent_proxy (this));
+ g_assert (mono_object_is_transparent_proxy (this_obj));
field_class = mono_class_from_mono_type (field->type);
if (!getter) {
getter = mono_class_get_method_from_name (mono_defaults.object_class, "FieldGetter", -1);
- g_assert (getter);
+ if (!getter)
+ mono_raise_exception (mono_get_exception_not_supported ("Linked away."));
}
msg = (MonoMethodMessage *)mono_object_new (domain, mono_defaults.mono_method_message_class);
/**
* mono_store_remote_field:
- * @this: pointer to an object
+ * @this_obj: pointer to an object
* @klass: klass of the object containing @field
* @field: the field to load
* @val: the value/object to store
*
* This method is called by the runtime on attempts to store fields of
- * transparent proxy objects. @this points to such TP, @klass is the class of
+ * transparent proxy objects. @this_obj points to such TP, @klass is the class of
* the object containing @field. @val is the new value to store in @field.
*/
void
-mono_store_remote_field (MonoObject *this, MonoClass *klass, MonoClassField *field, gpointer val)
+mono_store_remote_field (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, gpointer val)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static MonoMethod *setter = NULL;
MonoDomain *domain = mono_domain_get ();
- MonoTransparentProxy *tp = (MonoTransparentProxy *) this;
+ MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
MonoClass *field_class;
MonoMethodMessage *msg;
MonoArray *out_args;
MonoObject *arg;
char* full_name;
- g_assert (mono_object_is_transparent_proxy (this));
+ g_assert (mono_object_is_transparent_proxy (this_obj));
field_class = mono_class_from_mono_type (field->type);
if (!setter) {
setter = mono_class_get_method_from_name (mono_defaults.object_class, "FieldSetter", -1);
- g_assert (setter);
+ if (!setter)
+ mono_raise_exception (mono_get_exception_not_supported ("Linked away."));
}
if (field_class->valuetype)
/**
* mono_store_remote_field_new:
- * @this:
+ * @this_obj:
* @klass:
* @field:
* @arg:
* Missing documentation
*/
void
-mono_store_remote_field_new (MonoObject *this, MonoClass *klass, MonoClassField *field, MonoObject *arg)
+mono_store_remote_field_new (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, MonoObject *arg)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static MonoMethod *setter = NULL;
MonoDomain *domain = mono_domain_get ();
- MonoTransparentProxy *tp = (MonoTransparentProxy *) this;
+ MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
MonoClass *field_class;
MonoMethodMessage *msg;
MonoArray *out_args;
MonoObject *exc;
char* full_name;
- g_assert (mono_object_is_transparent_proxy (this));
+ g_assert (mono_object_is_transparent_proxy (this_obj));
field_class = mono_class_from_mono_type (field->type);
if (!setter) {
setter = mono_class_get_method_from_name (mono_defaults.object_class, "FieldSetter", -1);
- g_assert (setter);
+ if (!setter)
+ mono_raise_exception (mono_get_exception_not_supported ("Linked away."));
}
msg = (MonoMethodMessage *)mono_object_new (domain, mono_defaults.mono_method_message_class);
gunichar2 *
mono_string_chars (MonoString *s)
{
+ // MONO_REQ_GC_UNSAFE_MODE; //FIXME too much trouble for now
+
return s->chars;
}
int
mono_string_length (MonoString *s)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return s->length;
}
uintptr_t
mono_array_length (MonoArray *array)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return array->max_length;
}
char*
mono_array_addr_with_size (MonoArray *array, int size, uintptr_t idx)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return ((char*)(array)->vector) + size * idx;
}