#include <mono/metadata/gc-internal.h>
#include <mono/utils/strenc.h>
#include <mono/utils/mono-counters.h>
+#include "cominterop.h"
#ifdef HAVE_BOEHM_GC
#define NEED_TO_ZERO_PTRFREE 1
mono_image_check_for_module_cctor (klass->image);
if (klass->image->has_module_cctor) {
MonoClass *module_klass = mono_class_get (klass->image, MONO_TOKEN_TYPE_DEF | 1);
- mono_runtime_class_init (mono_class_vtable (vtable->domain, module_klass));
+ MonoVTable *module_vtable = mono_class_vtable_full (vtable->domain, module_klass, raise_exception);
+ if (!module_vtable)
+ return NULL;
+ mono_runtime_class_init (module_vtable);
}
}
method = mono_class_get_cctor (klass);
}
void
-mono_release_type_locks (MonoThread *thread)
+mono_release_type_locks (MonoInternalThread *thread)
{
mono_type_initialization_lock ();
g_hash_table_foreach_remove (type_initialization_hash, release_type_locks, (gpointer)(gsize)(thread->tid));
memcpy (&callbacks, cbs, sizeof (*cbs));
}
+MonoRuntimeCallbacks*
+mono_get_runtime_callbacks (void)
+{
+ return &callbacks;
+}
+
void
mono_install_trampoline (MonoTrampoline func)
{
mono_domain_unlock (domain);
}
-static MonoVTable *mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class);
+static MonoVTable *mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class, gboolean raise_on_error);
/**
* mono_class_vtable:
*/
MonoVTable *
mono_class_vtable (MonoDomain *domain, MonoClass *class)
+{
+ return mono_class_vtable_full (domain, class, FALSE);
+}
+
+/**
+ * mono_class_vtable_full:
+ * @domain: the application domain
+ * @class: the class to initialize
+ * @raise_on_error if an exception should be raised on failure or not
+ *
+ * VTables are domain specific because we create domain specific code, and
+ * they contain the domain specific static class data.
+ */
+MonoVTable *
+mono_class_vtable_full (MonoDomain *domain, MonoClass *class, gboolean raise_on_error)
{
MonoClassRuntimeInfo *runtime_info;
g_assert (class);
+ if (class->exception_type) {
+ if (raise_on_error)
+ mono_raise_exception (mono_class_get_exception_for_failure (class));
+ return NULL;
+ }
+
/* this check can be inlined in jitted code, too */
runtime_info = class->runtime_info;
if (runtime_info && runtime_info->max_domain >= domain->domain_id && runtime_info->domain_vtables [domain->domain_id])
return runtime_info->domain_vtables [domain->domain_id];
- if (class->exception_type)
- return NULL;
- return mono_class_create_runtime_vtable (domain, class);
+ return mono_class_create_runtime_vtable (domain, class, raise_on_error);
}
/**
}
static MonoVTable *
-mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class)
+mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class, gboolean raise_on_error)
{
MonoVTable *vt;
MonoClassRuntimeInfo *runtime_info, *old_info;
return runtime_info->domain_vtables [domain->domain_id];
}
if (!class->inited || class->exception_type) {
- if (!mono_class_init (class) || class->exception_type){
- MonoException *exc;
+ if (!mono_class_init (class) || class->exception_type) {
mono_domain_unlock (domain);
mono_loader_unlock ();
- exc = mono_class_get_exception_for_failure (class);
- g_assert (exc);
- mono_raise_exception (exc);
+ if (raise_on_error)
+ mono_raise_exception (mono_class_get_exception_for_failure (class));
+ return NULL;
}
}
- mono_class_init (class);
+ /* Array types require that their element type be valid*/
+ if (class->byval_arg.type == MONO_TYPE_ARRAY || class->byval_arg.type == MONO_TYPE_SZARRAY) {
+ MonoClass *element_class = class->element_class;
+ if (!element_class->inited)
+ mono_class_init (element_class);
+
+ /*mono_class_init can leave the vtable layout to be lazily done and we can't afford this here*/
+ if (element_class->exception_type == MONO_EXCEPTION_NONE && !element_class->vtable_size)
+ mono_class_setup_vtable (element_class);
+
+ if (element_class->exception_type != MONO_EXCEPTION_NONE) {
+ /*Can happen if element_class only got bad after mono_class_setup_vtable*/
+ if (class->exception_type == MONO_EXCEPTION_NONE)
+ mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_domain_unlock (domain);
+ mono_loader_unlock ();
+ if (raise_on_error)
+ mono_raise_exception (mono_class_get_exception_for_failure (class));
+ return NULL;
+ }
+ }
/*
* For some classes, mono_class_init () already computed class->vtable_size, and
if (class->exception_type) {
mono_domain_unlock (domain);
mono_loader_unlock ();
+ if (raise_on_error)
+ mono_raise_exception (mono_class_get_exception_for_failure (class));
return NULL;
}
if (ARCH_USE_IMT) {
- vtable_size = sizeof (MonoVTable) + class->vtable_size * sizeof (gpointer);
+ vtable_size = MONO_SIZEOF_VTABLE + class->vtable_size * sizeof (gpointer);
if (class->interface_offsets_count) {
imt_table_bytes = sizeof (gpointer) * (MONO_IMT_SIZE);
vtable_size += sizeof (gpointer) * (MONO_IMT_SIZE);
}
} else {
vtable_size = sizeof (gpointer) * (class->max_interface_id + 1) +
- sizeof (MonoVTable) + class->vtable_size * sizeof (gpointer);
+ MONO_SIZEOF_VTABLE + class->vtable_size * sizeof (gpointer);
}
mono_stats.used_class_count++;
/* this is a bounded memory retention issue: may want to
* handle it differently when we'll have a rcu-like system.
*/
- runtime_info = mono_image_alloc0 (class->image, sizeof (MonoClassRuntimeInfo) + new_size * sizeof (gpointer));
+ runtime_info = mono_image_alloc0 (class->image, MONO_SIZEOF_CLASS_RUNTIME_INFO + new_size * sizeof (gpointer));
runtime_info->max_domain = new_size - 1;
/* copy the stuff from the older info */
if (old_info) {
mono_loader_unlock ();
/* Initialization is now complete, we can throw if the InheritanceDemand aren't satisfied */
- if (mono_is_security_manager_active () && (class->exception_type == MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND)) {
- MonoException *exc = mono_class_get_exception_for_failure (class);
- g_assert (exc);
- mono_raise_exception (exc);
- }
+ if (mono_is_security_manager_active () && (class->exception_type == MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND) && raise_on_error)
+ mono_raise_exception (mono_class_get_exception_for_failure (class));
/* make sure the parent is initialized */
+ /*FIXME shouldn't this fail the current type?*/
if (class->parent)
- mono_class_vtable (domain, class->parent);
+ mono_class_vtable_full (domain, class->parent, raise_on_error);
+ /*FIXME check for OOM*/
vt->type = mono_type_get_object (domain, &class->byval_arg);
if (class->contextbound)
vt->remote = 1;
gpointer *interface_offsets;
vt = mono_class_vtable (domain, class);
+ g_assert (vt); /*FIXME property handle failure*/
max_interface_id = vt->max_interface_id;
/* Calculate vtable space for extra interfaces */
mono_stats.imt_number_of_tables++;
mono_stats.imt_tables_size += (sizeof (gpointer) * MONO_IMT_SIZE);
vtsize = sizeof (gpointer) * (MONO_IMT_SIZE) +
- sizeof (MonoVTable) + class->vtable_size * sizeof (gpointer);
+ MONO_SIZEOF_VTABLE + class->vtable_size * sizeof (gpointer);
} else {
vtsize = sizeof (gpointer) * (max_interface_id + 1) +
- sizeof (MonoVTable) + class->vtable_size * sizeof (gpointer);
+ MONO_SIZEOF_VTABLE + class->vtable_size * sizeof (gpointer);
}
mono_stats.class_vtable_size += vtsize + extra_interface_vtsize;
pvt = (MonoVTable*) (interface_offsets + MONO_IMT_SIZE);
else
pvt = (MonoVTable*) (interface_offsets + max_interface_id + 1);
- memcpy (pvt, vt, sizeof (MonoVTable) + class->vtable_size * sizeof (gpointer));
+ memcpy (pvt, vt, MONO_SIZEOF_VTABLE + class->vtable_size * sizeof (gpointer));
pvt->klass = mono_defaults.transparent_proxy_class;
/* we need to keep the GC descriptor for a transparent proxy or we confuse the precise GC */
key = mp_key;
if (proxy_class->flags & TYPE_ATTRIBUTE_INTERFACE) {
- rc = mono_domain_alloc (domain, sizeof(MonoRemoteClass) + sizeof(MonoClass*));
+ rc = mono_domain_alloc (domain, MONO_SIZEOF_REMOTE_CLASS + sizeof(MonoClass*));
rc->interface_count = 1;
rc->interfaces [0] = proxy_class;
rc->proxy_class = mono_defaults.marshalbyrefobject_class;
} else {
- rc = mono_domain_alloc (domain, sizeof(MonoRemoteClass));
+ rc = mono_domain_alloc (domain, MONO_SIZEOF_REMOTE_CLASS);
rc->interface_count = 0;
rc->proxy_class = proxy_class;
}
if (extra_class->flags & TYPE_ATTRIBUTE_INTERFACE) {
int i,j;
- rc = mono_domain_alloc (domain, sizeof(MonoRemoteClass) + sizeof(MonoClass*) * (remote_class->interface_count + 1));
+ rc = mono_domain_alloc (domain, MONO_SIZEOF_REMOTE_CLASS + sizeof(MonoClass*) * (remote_class->interface_count + 1));
rc->proxy_class = remote_class->proxy_class;
rc->interface_count = remote_class->interface_count + 1;
rc->interfaces [j] = extra_class;
} else {
// Replace the old class. The interface array is the same
- rc = mono_domain_alloc (domain, sizeof(MonoRemoteClass) + sizeof(MonoClass*) * remote_class->interface_count);
+ rc = mono_domain_alloc (domain, MONO_SIZEOF_REMOTE_CLASS + sizeof(MonoClass*) * remote_class->interface_count);
rc->proxy_class = extra_class;
rc->interface_count = remote_class->interface_count;
if (rc->interface_count > 0)
/* generic methods demand invoke_with_check */
if (mono_method_signature (res)->generic_param_count)
res = mono_marshal_get_remoting_invoke_with_check (res);
- else
- res = mono_marshal_get_remoting_invoke (res);
+ else {
+#ifndef DISABLE_COM
+ if (klass == mono_defaults.com_object_class || klass->is_com_object)
+ res = mono_cominterop_get_invoke (res);
+ else
+#endif
+ res = mono_marshal_get_remoting_invoke (res);
+ }
} else {
if (method->is_inflated) {
/* Have to inflate the result */
} else {
MonoClass *class = mono_class_from_mono_type (type);
int size = mono_class_value_size (class, NULL);
- if (value == NULL) {
+ if (value == NULL)
memset (dest, 0, size);
- } else {
- memcpy (dest, value, size);
- mono_gc_wbarrier_value_copy (dest, value, size, class);
- }
+ else
+ mono_gc_wbarrier_value_copy (dest, value, 1, class);
}
return;
case MONO_TYPE_GENERICINST:
if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
is_static = TRUE;
vtable = mono_class_vtable (domain, field->parent);
+ if (!vtable) {
+ char *name = mono_type_get_full_name (field->parent);
+ g_warning ("Could not retrieve the vtable for type %s in mono_field_get_value_object", name);
+ g_free (name);
+ return NULL;
+ }
if (!vtable->initialized)
mono_runtime_class_init (vtable);
}
g_assert (mono_class_from_mono_type (klass->fields [1].type) == mono_defaults.boolean_class);
*(guint8*)(buf + klass->fields [1].offset - sizeof (MonoObject)) = value ? 1 : 0;
- if (value)
- memcpy (buf + klass->fields [0].offset - sizeof (MonoObject), mono_object_unbox (value), mono_class_value_size (param_class, NULL));
- else
+ if (value) {
+ if (param_class->has_references)
+ mono_gc_wbarrier_value_copy (buf + klass->fields [0].offset - sizeof (MonoObject), mono_object_unbox (value), 1, param_class);
+ else
+ memcpy (buf + klass->fields [0].offset - sizeof (MonoObject), mono_object_unbox (value), mono_class_value_size (param_class, NULL));
+ } else {
memset (buf + klass->fields [0].offset - sizeof (MonoObject), 0, mono_class_value_size (param_class, NULL));
+ }
}
/**
if (*(guint8*)(buf + klass->fields [1].offset - sizeof (MonoObject))) {
MonoObject *o = mono_object_new (mono_domain_get (), param_class);
- memcpy (mono_object_unbox (o), buf + klass->fields [0].offset - sizeof (MonoObject), mono_class_value_size (param_class, NULL));
+ if (param_class->has_references)
+ mono_gc_wbarrier_value_copy (mono_object_unbox (o), buf + klass->fields [0].offset - sizeof (MonoObject), 1, param_class);
+ else
+ memcpy (mono_object_unbox (o), buf + klass->fields [0].offset - sizeof (MonoObject), mono_class_value_size (param_class, NULL));
return o;
}
else
return result;
}
+static MonoObject*
+serialize_object (MonoObject *obj, gboolean *failure, MonoObject **exc)
+{
+ static MonoMethod *serialize_method;
+
+ void *params [1];
+ MonoObject *array;
+
+ if (!serialize_method) {
+ MonoClass *klass = mono_class_from_name (mono_defaults.corlib, "System.Runtime.Remoting", "RemotingServices");
+ serialize_method = mono_class_get_method_from_name (klass, "SerializeCallData", -1);
+ }
+
+ if (!serialize_method) {
+ *failure = TRUE;
+ return NULL;
+ }
+
+ g_assert (!mono_object_class (obj)->marshalbyref);
+
+ params [0] = obj;
+ *exc = NULL;
+ array = mono_runtime_invoke (serialize_method, NULL, params, exc);
+ if (*exc)
+ *failure = TRUE;
+
+ return array;
+}
+
+static MonoObject*
+deserialize_object (MonoObject *obj, gboolean *failure, MonoObject **exc)
+{
+ static MonoMethod *deserialize_method;
+
+ void *params [1];
+ MonoObject *result;
+
+ if (!deserialize_method) {
+ MonoClass *klass = mono_class_from_name (mono_defaults.corlib, "System.Runtime.Remoting", "RemotingServices");
+ deserialize_method = mono_class_get_method_from_name (klass, "DeserializeCallData", -1);
+ }
+ if (!deserialize_method) {
+ *failure = TRUE;
+ return NULL;
+ }
+
+ params [0] = obj;
+ *exc = NULL;
+ result = mono_runtime_invoke (deserialize_method, NULL, params, exc);
+ if (*exc)
+ *failure = TRUE;
+
+ return result;
+}
+
+static MonoObject*
+make_transparent_proxy (MonoObject *obj, gboolean *failure, MonoObject **exc)
+{
+ static MonoMethod *get_proxy_method;
+
+ MonoDomain *domain = mono_domain_get ();
+ MonoRealProxy *real_proxy;
+ MonoReflectionType *reflection_type;
+ MonoTransparentProxy *transparent_proxy;
+
+ if (!get_proxy_method)
+ get_proxy_method = mono_class_get_method_from_name (mono_defaults.real_proxy_class, "GetTransparentProxy", 0);
+
+ g_assert (obj->vtable->klass->marshalbyref);
+
+ real_proxy = (MonoRealProxy*) mono_object_new (domain, mono_defaults.real_proxy_class);
+ reflection_type = mono_type_get_object (domain, &obj->vtable->klass->byval_arg);
+
+ MONO_OBJECT_SETREF (real_proxy, class_to_proxy, reflection_type);
+ MONO_OBJECT_SETREF (real_proxy, unwrapped_server, obj);
+
+ *exc = NULL;
+ transparent_proxy = (MonoTransparentProxy*) mono_runtime_invoke (get_proxy_method, real_proxy, NULL, exc);
+ if (*exc)
+ *failure = TRUE;
+
+ return (MonoObject*) transparent_proxy;
+}
+
+/**
+ * mono_object_xdomain_representation
+ * @obj: an object
+ * @target_domain: a domain
+ * @exc: pointer to a MonoObject*
+ *
+ * Creates a representation of obj in the domain target_domain. This
+ * is either a copy of obj arrived through via serialization and
+ * deserialization or a proxy, depending on whether the object is
+ * serializable or marshal by ref. obj must not be in target_domain.
+ *
+ * If the object cannot be represented in target_domain, NULL is
+ * returned and *exc is set to an appropriate exception.
+ */
+MonoObject*
+mono_object_xdomain_representation (MonoObject *obj, MonoDomain *target_domain, MonoObject **exc)
+{
+ MonoObject *deserialized = NULL;
+ gboolean failure = FALSE;
+
+ *exc = NULL;
+
+ if (mono_object_class (obj)->marshalbyref) {
+ deserialized = make_transparent_proxy (obj, &failure, exc);
+ } else {
+ MonoDomain *domain = mono_domain_get ();
+ MonoObject *serialized;
+
+ mono_domain_set_internal_with_options (mono_object_domain (obj), FALSE);
+ serialized = serialize_object (obj, &failure, exc);
+ mono_domain_set_internal_with_options (target_domain, FALSE);
+ if (!failure)
+ deserialized = deserialize_object (serialized, &failure, exc);
+ if (domain != target_domain)
+ mono_domain_set_internal_with_options (domain, FALSE);
+ }
+
+ return deserialized;
+}
+
/* Used in call_unhandled_exception_delegate */
static MonoObject *
create_unhandled_exception_eventargs (MonoObject *exc)
call_unhandled_exception_delegate (MonoDomain *domain, MonoObject *delegate, MonoObject *exc) {
MonoObject *e = NULL;
gpointer pa [2];
+ MonoDomain *current_domain = mono_domain_get ();
+
+ if (domain != current_domain)
+ mono_domain_set_internal_with_options (domain, FALSE);
+
+ g_assert (domain == mono_object_domain (domain->domain));
+
+ if (mono_object_domain (exc) != domain) {
+ MonoObject *serialization_exc;
+
+ exc = mono_object_xdomain_representation (exc, domain, &serialization_exc);
+ if (!exc) {
+ if (serialization_exc) {
+ MonoObject *dummy;
+ exc = mono_object_xdomain_representation (serialization_exc, domain, &dummy);
+ g_assert (exc);
+ } else {
+ exc = (MonoObject*) mono_exception_from_name_msg (mono_get_corlib (),
+ "System.Runtime.Serialization", "SerializationException",
+ "Could not serialize unhandled exception.");
+ }
+ }
+ }
+ g_assert (mono_object_domain (exc) == domain);
pa [0] = domain->domain;
pa [1] = create_unhandled_exception_eventargs (exc);
mono_runtime_delegate_invoke (delegate, pa, &e);
-
+
+ if (domain != current_domain)
+ mono_domain_set_internal_with_options (current_domain, FALSE);
+
if (e) {
gchar *msg = mono_string_to_utf8 (((MonoException *) e)->message);
g_warning ("exception inside UnhandledException handler: %s\n", msg);
g_assert (field);
if (exc->vtable->klass != mono_defaults.threadabortexception_class) {
- gboolean abort_process = (mono_thread_current () == main_thread) ||
+ gboolean abort_process = (main_thread && (mono_thread_internal_current () == main_thread->internal_thread)) ||
(mono_runtime_unhandled_exception_policy_get () == MONO_UNHANDLED_POLICY_CURRENT);
root_appdomain_delegate = *(MonoObject **)(((char *)root_domain->domain) + field->offset);
if (current_domain != root_domain && (mono_framework_version () >= 2)) {
int rval;
MonoCustomAttrInfo* cinfo;
gboolean has_stathread_attribute;
- MonoThread* thread = mono_thread_current ();
+ MonoInternalThread* thread = mono_thread_internal_current ();
g_assert (args);
* looked up using @klass. This will not invoke any constructors,
* so the consumer of this routine has to invoke any constructors on
* its own to initialize the object.
+ *
+ * It returns NULL on failure.
*/
MonoObject *
mono_object_new (MonoDomain *domain, MonoClass *klass)
{
+ MonoVTable *vtable;
+
MONO_ARCH_SAVE_REGS;
- return mono_object_new_specific (mono_class_vtable (domain, klass));
+ vtable = mono_class_vtable (domain, klass);
+ if (!vtable)
+ return NULL;
+ return mono_object_new_specific (vtable);
}
/**
mono_object_clone (MonoObject *obj)
{
MonoObject *o;
- int size;
+ int size = obj->vtable->klass->instance_size;
- size = obj->vtable->klass->instance_size;
o = mono_object_allocate (size, obj->vtable);
- /* do not copy the sync state */
- memcpy ((char*)o + sizeof (MonoObject), (char*)obj + sizeof (MonoObject), size - sizeof (MonoObject));
-#ifdef HAVE_SGEN_GC
- if (obj->vtable->klass->has_references)
- mono_gc_wbarrier_object (o);
-#endif
+ if (obj->vtable->klass->has_references) {
+ mono_gc_wbarrier_object_copy (o, obj);
+ } else {
+ int size = obj->vtable->klass->instance_size;
+ /* do not copy the sync state */
+ memcpy ((char*)o + sizeof (MonoObject), (char*)obj + sizeof (MonoObject), size - sizeof (MonoObject));
+ }
if (G_UNLIKELY (profile_allocs))
mono_profiler_allocation (o, obj->vtable->klass);
((guint32)(b) > ((MYGUINT32_MAX) / (guint32)(a)))))
#endif
+gboolean
+mono_array_calc_byte_len (MonoClass *class, mono_array_size_t len, mono_array_size_t *res)
+{
+ mono_array_size_t byte_len;
+
+ byte_len = mono_array_element_size (class);
+ if (CHECK_MUL_OVERFLOW_UN (byte_len, len))
+ return FALSE;
+ byte_len *= len;
+ if (CHECK_ADD_OVERFLOW_UN (byte_len, sizeof (MonoArray)))
+ return FALSE;
+ byte_len += sizeof (MonoArray);
+
+ *res = byte_len;
+
+ return TRUE;
+}
+
/**
* mono_array_new_full:
* @domain: domain where the object is created
mono_array_size_t byte_len, len, bounds_size;
MonoObject *o;
MonoArray *array;
+ MonoArrayBounds *bounds;
MonoVTable *vtable;
int i;
if (!array_class->inited)
mono_class_init (array_class);
- byte_len = mono_array_element_size (array_class);
len = 1;
/* A single dimensional array with a 0 lower bound is the same as an szarray */
}
}
- if (CHECK_MUL_OVERFLOW_UN (byte_len, len))
- mono_gc_out_of_memory (MONO_ARRAY_MAX_SIZE);
- byte_len *= len;
- if (CHECK_ADD_OVERFLOW_UN (byte_len, sizeof (MonoArray)))
+ if (!mono_array_calc_byte_len (array_class, len, &byte_len))
mono_gc_out_of_memory (MONO_ARRAY_MAX_SIZE);
- byte_len += sizeof (MonoArray);
+
if (bounds_size) {
/* align */
if (CHECK_ADD_OVERFLOW_UN (byte_len, 3))
* Following three lines almost taken from mono_object_new ():
* they need to be kept in sync.
*/
- vtable = mono_class_vtable (domain, array_class);
+ 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
array->max_length = len;
if (bounds_size) {
- MonoArrayBounds *bounds = (MonoArrayBounds*)((char*)array + byte_len - 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
+ o = mono_gc_alloc_vector (vtable, byte_len, len);
+ array = (MonoArray*)o;
+ mono_stats.new_object_count++;
+
+ bounds = array->bounds;
+#endif
+
+ if (bounds_size) {
for (i = 0; i < array_class->rank; ++i) {
bounds [i].length = lengths [i];
if (lower_bounds)
ac = mono_array_class_get (eclass, 1);
g_assert (ac);
- return mono_array_new_specific (mono_class_vtable (domain, ac), n);
+ return mono_array_new_specific (mono_class_vtable_full (domain, ac, TRUE), n);
}
/**
{
MonoObject *o;
MonoArray *ao;
- guint32 byte_len, elem_size;
+ guint32 byte_len;
MONO_ARCH_SAVE_REGS;
arith_overflow ();
return NULL;
}
-
- elem_size = mono_array_element_size (vtable->klass);
- if (CHECK_MUL_OVERFLOW_UN (n, elem_size)) {
- mono_gc_out_of_memory (MONO_ARRAY_MAX_SIZE);
- return NULL;
- }
- byte_len = n * elem_size;
- if (CHECK_ADD_OVERFLOW_UN (byte_len, sizeof (MonoArray))) {
+
+ if (!mono_array_calc_byte_len (vtable->klass, n, &byte_len)) {
mono_gc_out_of_memory (MONO_ARRAY_MAX_SIZE);
return NULL;
}
- byte_len += sizeof (MonoArray);
+#ifndef HAVE_SGEN_GC
if (!vtable->klass->has_references) {
o = mono_object_allocate_ptrfree (byte_len, vtable);
#if NEED_TO_ZERO_PTRFREE
ao = (MonoArray *)o;
ao->max_length = n;
+#else
+ o = mono_gc_alloc_vector (vtable, byte_len, n);
+ ao = (MonoArray*)o;
+ mono_stats.new_object_count++;
+#endif
+
if (G_UNLIKELY (profile_allocs))
mono_profiler_allocation (o, vtable->klass);
mono_gc_out_of_memory (-1);
vtable = mono_class_vtable (domain, mono_defaults.string_class);
+ g_assert (vtable);
s = mono_object_allocate_ptrfree (size, vtable);
return mono_nullable_box (value, class);
vtable = mono_class_vtable (domain, class);
+ if (!vtable)
+ return NULL;
size = mono_class_instance_size (class);
res = mono_object_new_alloc_specific (vtable);
if (G_UNLIKELY (profile_allocs))
size = size - sizeof (MonoObject);
#ifdef HAVE_SGEN_GC
+ g_assert (size == mono_class_value_size (class, NULL));
mono_gc_wbarrier_value_copy ((char *)res + sizeof (MonoObject), value, 1, class);
-#endif
-
+#else
#if NO_UNALIGNED_ACCESS
memcpy ((char *)res + sizeof (MonoObject), value, size);
#else
default:
memcpy ((char *)res + sizeof (MonoObject), value, size);
}
+#endif
#endif
if (class->has_finalize)
mono_object_register_finalizer (res);
void
mono_value_copy (gpointer dest, gpointer src, MonoClass *klass)
{
- int size = mono_class_value_size (klass, NULL);
mono_gc_wbarrier_value_copy (dest, src, 1, klass);
- memcpy (dest, src, size);
}
/*
{
int size = mono_array_element_size (dest->obj.vtable->klass);
char *d = mono_array_addr_with_size (dest, size, dest_idx);
+ g_assert (size == mono_class_value_size (mono_object_class (dest)->element_class, NULL));
mono_gc_wbarrier_value_copy (d, src, count, mono_object_class (dest)->element_class);
- memmove (d, src, size * count);
}
/**
*/
if (((MonoObject*)ex)->vtable->klass == mono_defaults.threadabortexception_class) {
- MonoThread *thread = mono_thread_current ();
+ MonoInternalThread *thread = mono_thread_internal_current ();
g_assert (ex->object.vtable->domain == mono_domain_get ());
MONO_OBJECT_SETREF (thread, abort_exc, ex);
}
gpointer params [1];
static MonoMethod *handle_set;
- res = (MonoWaitHandle *)mono_object_new (domain, mono_defaults.waithandle_class);
+ res = (MonoWaitHandle *)mono_object_new (domain, mono_defaults.manualresetevent_class);
/* Even though this method is virtual, it's safe to invoke directly, since the object type matches. */
if (!handle_set)
- handle_set = mono_class_get_property_from_name (mono_defaults.waithandle_class, "Handle")->set;
+ handle_set = mono_class_get_property_from_name (mono_defaults.manualresetevent_class, "Handle")->set;
params [0] = &handle;
mono_runtime_invoke (handle_set, res, params, NULL);
static MonoClassField *f_safe_handle;
if (!f_os_handle && !f_safe_handle) {
- f_os_handle = mono_class_get_field_from_name (mono_defaults.waithandle_class, "os_handle");
- f_safe_handle = mono_class_get_field_from_name (mono_defaults.waithandle_class, "safe_wait_handle");
+ f_os_handle = mono_class_get_field_from_name (mono_defaults.manualresetevent_class, "os_handle");
+ f_safe_handle = mono_class_get_field_from_name (mono_defaults.manualresetevent_class, "safe_wait_handle");
}
if (f_os_handle) {
method = mono_marshal_get_remoting_invoke (method);
delegate->method_ptr = mono_compile_method (method);
MONO_OBJECT_SETREF (delegate, target, target);
- } else if (mono_method_signature (method)->hasthis && method->klass->valuetype) {
+ } else if (method && mono_method_signature (method)->hasthis && method->klass->valuetype) {
method = mono_marshal_get_unbox_wrapper (method);
delegate->method_ptr = mono_compile_method (method);
MONO_OBJECT_SETREF (delegate, target, target);
arg = mono_array_get (out_args, gpointer, j);
type = pt->type;
- switch (type) {
- case MONO_TYPE_VOID:
- g_assert_not_reached ();
- break;
- case MONO_TYPE_U1:
- case MONO_TYPE_I1:
- case MONO_TYPE_BOOLEAN:
- case MONO_TYPE_U2:
- case MONO_TYPE_I2:
- case MONO_TYPE_CHAR:
- case MONO_TYPE_U4:
- case MONO_TYPE_I4:
- case MONO_TYPE_I8:
- case MONO_TYPE_U8:
- case MONO_TYPE_R4:
- case MONO_TYPE_R8:
- case MONO_TYPE_VALUETYPE: {
+ g_assert (type != MONO_TYPE_VOID);
+
+ if (MONO_TYPE_IS_REFERENCE (pt)) {
+ mono_gc_wbarrier_generic_store (*((MonoObject ***)params [i]), (MonoObject *)arg);
+ } else {
if (arg) {
- size = mono_class_value_size (((MonoObject*)arg)->vtable->klass, NULL);
- memcpy (*((gpointer *)params [i]), arg + sizeof (MonoObject), size);
- }
- else {
+ MonoClass *class = ((MonoObject*)arg)->vtable->klass;
+ size = mono_class_value_size (class, NULL);
+ if (class->has_references)
+ mono_gc_wbarrier_value_copy (*((gpointer *)params [i]), arg + sizeof (MonoObject), 1, class);
+ else
+ memcpy (*((gpointer *)params [i]), arg + sizeof (MonoObject), size);
+ } else {
size = mono_class_value_size (mono_class_from_mono_type (pt), NULL);
memset (*((gpointer *)params [i]), 0, size);
}
- break;
- }
- case MONO_TYPE_STRING:
- case MONO_TYPE_CLASS:
- case MONO_TYPE_ARRAY:
- case MONO_TYPE_SZARRAY:
- case MONO_TYPE_OBJECT:
- **((MonoObject ***)params [i]) = (MonoObject *)arg;
- break;
- default:
- g_assert_not_reached ();
}
j++;