size = max_size;
}
+#ifdef HAVE_SGEN_GC
+ /*An Ephemeron cannot be marked by sgen*/
+ if (!static_fields && class->image == mono_defaults.corlib && !strcmp ("Ephemeron", class->name)) {
+ *max_set = 0;
+ memset (bitmap, 0, size / 8);
+ return bitmap;
+ }
+#endif
+
for (p = class; p != NULL; p = p->parent) {
gpointer iter = NULL;
while ((field = mono_class_get_fields (p, &iter))) {
imt_trampoline = tramp_code;
}
-static gpointer vtable_trampoline = NULL;
-
-void
-mono_install_vtable_trampoline (gpointer tramp_code)
-{
- vtable_trampoline = tramp_code;
-}
-
#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
#define mix(a,b,c) { \
a -= c; a ^= rot(c, 4); c += b; \
* 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
if (++gvc->count == THUNK_THRESHOLD) {
gpointer *old_thunk = *vtable_slot;
+ gpointer vtable_trampoline = callbacks.get_vtable_trampoline ? callbacks.get_vtable_trampoline ((gpointer*)vtable_slot - (gpointer*)vtable) : NULL;
if ((gpointer)vtable_slot < (gpointer)vtable)
/* Force the rebuild of the thunk at the next call */
if (special_static != SPECIAL_STATIC_NONE) {
guint32 size, offset;
gint32 align;
+ gsize default_bitmap [4] = {0};
+ gsize *bitmap;
+ int max_set = 0;
+ MonoClass *fclass;
+ if (mono_type_is_reference (field->type)) {
+ default_bitmap [0] = 1;
+ max_set = 1;
+ bitmap = default_bitmap;
+ } else if (mono_type_is_struct (field->type)) {
+ fclass = mono_class_from_mono_type (field->type);
+ bitmap = compute_class_bitmap (fclass, default_bitmap, sizeof (default_bitmap) * 8, 0, &max_set, FALSE);
+ } else {
+ default_bitmap [0] = 0;
+ max_set = 0;
+ bitmap = default_bitmap;
+ }
size = mono_type_size (field->type, &align);
- offset = mono_alloc_special_static_data (special_static, size, align);
+ offset = mono_alloc_special_static_data (special_static, size, align, bitmap, max_set);
if (!domain->special_static_fields)
domain->special_static_fields = g_hash_table_new (NULL, NULL);
g_hash_table_insert (domain->special_static_fields, field, GUINT_TO_POINTER (offset));
+ if (bitmap != default_bitmap)
+ g_free (bitmap);
/*
* This marks the field as special static to speed up the
* checks in mono_field_static_get/set_value ().
}
}
- /* FIXME: class_vtable_hash is basically obsolete now: remove as soon
- * as we change the code in appdomain.c to invalidate vtables by
- * looking at the possible MonoClasses created for the domain.
+ /* class_vtable_array keeps an array of created vtables
*/
- g_hash_table_insert (domain->class_vtable_hash, class, vt);
+ g_ptr_array_add (domain->class_vtable_array, vt);
/* class->runtime_info is protected by the loader lock, both when
* it it enlarged and when it is stored info.
*/
}
/* Initialize vtable */
- if (vtable_trampoline) {
+ if (callbacks.get_vtable_trampoline) {
// This also covers the AOT case
for (i = 0; i < class->vtable_size; ++i) {
- vt->vtable [i] = vtable_trampoline;
+ vt->vtable [i] = callbacks.get_vtable_trampoline (i);
}
} else {
mono_class_setup_vtable (class);
MonoMethod *cm;
if ((cm = class->vtable [i]))
- vt->vtable [i] = vtable_trampoline? vtable_trampoline: arch_create_jit_trampoline (cm);
+ vt->vtable [i] = arch_create_jit_trampoline (cm);
}
}
/*FIXME check for OOM*/
vt->type = mono_type_get_object (domain, &class->byval_arg);
+#if HAVE_SGEN_GC
+ if (mono_object_get_class (vt->type) != mono_defaults.monotype_class) {
+ static void *type_desc = NULL;
+
+ if (!type_desc) {
+ gsize bmap = 1;
+ type_desc = mono_gc_make_descr_from_bitmap (&bmap, 1);
+ }
+
+ /* This is unregistered in
+ unregister_vtable_reflection_type() in
+ domain.c. */
+ mono_gc_register_root ((char*)&vt->type, sizeof (gpointer), type_desc);
+ }
+#endif
if (class->contextbound)
vt->remote = 1;
else
GSList *extra_interfaces = NULL;
MonoClass *class = remote_class->proxy_class;
gpointer *interface_offsets;
+ uint8_t *bitmap;
+ int bsize;
+
+#ifdef COMPRESSED_INTERFACE_BITMAP
+ int bcsize;
+#endif
vt = mono_class_vtable (domain, class);
g_assert (vt); /*FIXME property handle failure*/
}
pvt->max_interface_id = max_interface_id;
- pvt->interface_bitmap = mono_domain_alloc0 (domain, sizeof (guint8) * (max_interface_id/8 + 1 ));
+ bsize = sizeof (guint8) * (max_interface_id/8 + 1 );
+#ifdef COMPRESSED_INTERFACE_BITMAP
+ bitmap = g_malloc0 (bsize);
+#else
+ bitmap = mono_domain_alloc0 (domain, bsize);
+#endif
if (! ARCH_USE_IMT) {
/* initialize interface offsets */
}
for (i = 0; i < class->interface_offsets_count; ++i) {
int interface_id = class->interfaces_packed [i]->interface_id;
- pvt->interface_bitmap [interface_id >> 3] |= (1 << (interface_id & 7));
+ bitmap [interface_id >> 3] |= (1 << (interface_id & 7));
}
if (extra_interfaces) {
if (! ARCH_USE_IMT) {
interface_offsets [max_interface_id - interf->interface_id] = &pvt->vtable [slot];
}
- pvt->interface_bitmap [interf->interface_id >> 3] |= (1 << (interf->interface_id & 7));
+ bitmap [interf->interface_id >> 3] |= (1 << (interf->interface_id & 7));
iter = NULL;
j = 0;
}
}
+#ifdef COMPRESSED_INTERFACE_BITMAP
+ bcsize = mono_compress_bitmap (NULL, bitmap, bsize);
+ pvt->interface_bitmap = mono_domain_alloc0 (domain, bcsize);
+ mono_compress_bitmap (pvt->interface_bitmap, bitmap, bsize);
+ g_free (bitmap);
+#else
+ pvt->interface_bitmap = bitmap;
+#endif
return pvt;
}
return vt->data;
}
+static guint8*
+mono_field_get_addr (MonoObject *obj, MonoVTable *vt, MonoClassField *field)
+{
+ guint8 *src;
+
+ if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
+ if (field->offset == -1) {
+ /* Special static */
+ gpointer addr = g_hash_table_lookup (vt->domain->special_static_fields, field);
+ src = mono_get_special_static_data (GPOINTER_TO_UINT (addr));
+ } else {
+ src = (guint8*)vt->data + field->offset;
+ }
+ } else {
+ src = (guint8*)obj + field->offset;
+ }
+
+ return src;
+}
+
/**
* mono_field_get_value:
* @obj: Object instance
{
void *src;
+ g_assert (obj);
+
g_return_if_fail (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC));
src = (char*)obj + field->offset;
gchar *v;
gboolean is_static = FALSE;
gboolean is_ref = FALSE;
+ gboolean is_literal = FALSE;
switch (field->type->type) {
case MONO_TYPE_STRING:
is_ref = field->type->byref;
break;
case MONO_TYPE_GENERICINST:
- is_ref = !field->type->data.generic_class->container_class->valuetype;
+ is_ref = !mono_type_generic_inst_is_valuetype (field->type);
break;
default:
g_error ("type 0x%x not handled in "
return NULL;
}
+ if (field->type->attrs & FIELD_ATTRIBUTE_LITERAL)
+ is_literal = TRUE;
+
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 (!is_literal) {
+ vtable = mono_class_vtable (domain, field->parent);
+ if (!vtable) {
+ char *name = mono_type_get_full_name (field->parent);
+ /*FIXME extend this to use the MonoError api*/
+ 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);
}
- if (!vtable->initialized)
- mono_runtime_class_init (vtable);
+ } else {
+ g_assert (obj);
}
if (is_ref) {
- if (is_static) {
+ if (is_literal) {
+ get_default_field_value (domain, field, &o);
+ } else if (is_static) {
mono_field_static_get_value (vtable, field, &o);
} else {
mono_field_get_value (obj, field, &o);
/* boxed value type */
klass = mono_class_from_mono_type (field->type);
+
+ if (mono_class_is_nullable (klass))
+ return mono_nullable_box (mono_field_get_addr (obj, vtable, field), klass);
+
o = mono_object_new (domain, klass);
v = ((gchar *) o) + sizeof (MonoObject);
- if (is_static) {
+
+ if (is_literal) {
+ get_default_field_value (domain, field, v);
+ } else if (is_static) {
mono_field_static_get_value (vtable, field, v);
} else {
mono_field_get_value (obj, field, v);
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)) {
+ if (current_domain != root_domain) {
current_appdomain_delegate = *(MonoObject **)(((char *)current_domain->domain) + field->offset);
} else {
current_appdomain_delegate = NULL;
}
}
-/*
+/**
+ * mono_runtime_exec_managed_code:
+ * @domain: Application domain
+ * @main_func: function to invoke from the execution thread
+ * @main_args: parameter to the main_func
+ *
* Launch a new thread to execute a function
*
* main_func is called back from the thread with main_args as the
}
if (has_stathread_attribute) {
thread->apartment_state = ThreadApartmentState_STA;
- } else if (mono_framework_version () == 1) {
- thread->apartment_state = ThreadApartmentState_Unknown;
} else {
thread->apartment_state = ThreadApartmentState_MTA;
}
if (!obj) {
obj = mono_object_new (mono_domain_get (), method->klass);
+ g_assert (obj); /*maybe we should raise a TLE instead?*/
if (mono_object_class(obj) == mono_defaults.transparent_proxy_class) {
method = mono_marshal_get_remoting_invoke (method->slot == -1 ? method : method->klass->vtable [method->slot]);
}
void
mono_array_full_copy (MonoArray *src, MonoArray *dest)
{
- mono_array_size_t size;
+ uintptr_t size;
MonoClass *klass = src->obj.vtable->klass;
MONO_ARCH_SAVE_REGS;
mono_array_clone_in_domain (MonoDomain *domain, MonoArray *array)
{
MonoArray *o;
- mono_array_size_t size, i;
- mono_array_size_t *sizes;
+ uintptr_t size, i;
+ uintptr_t *sizes;
MonoClass *klass = array->obj.vtable->klass;
MONO_ARCH_SAVE_REGS;
return o;
}
- sizes = alloca (klass->rank * sizeof(mono_array_size_t) * 2);
+ sizes = alloca (klass->rank * sizeof(intptr_t) * 2);
size = mono_array_element_size (klass);
for (i = 0; i < klass->rank; ++i) {
sizes [i] = array->bounds [i].length;
size *= array->bounds [i].length;
sizes [i + klass->rank] = array->bounds [i].lower_bound;
}
- o = mono_array_new_full (domain, klass, sizes, sizes + klass->rank);
+ o = mono_array_new_full (domain, klass, sizes, (intptr_t*)sizes + klass->rank);
#ifdef HAVE_SGEN_GC
if (klass->element_class->valuetype) {
if (klass->element_class->has_references)
#endif
gboolean
-mono_array_calc_byte_len (MonoClass *class, mono_array_size_t len, mono_array_size_t *res)
+mono_array_calc_byte_len (MonoClass *class, uintptr_t len, uintptr_t *res)
{
- mono_array_size_t byte_len;
+ uintptr_t byte_len;
byte_len = mono_array_element_size (class);
if (CHECK_MUL_OVERFLOW_UN (byte_len, len))
* lower bounds and type.
*/
MonoArray*
-mono_array_new_full (MonoDomain *domain, MonoClass *array_class, mono_array_size_t *lengths, mono_array_size_t *lower_bounds)
+mono_array_new_full (MonoDomain *domain, MonoClass *array_class, uintptr_t *lengths, intptr_t *lower_bounds)
{
- mono_array_size_t byte_len, len, bounds_size;
+ uintptr_t byte_len, len, bounds_size;
MonoObject *o;
MonoArray *array;
MonoArrayBounds *bounds;
* This routine creates a new szarray with @n elements of type @eclass.
*/
MonoArray *
-mono_array_new (MonoDomain *domain, MonoClass *eclass, mono_array_size_t n)
+mono_array_new (MonoDomain *domain, MonoClass *eclass, uintptr_t n)
{
MonoClass *ac;
* can be sure about the domain it operates in.
*/
MonoArray *
-mono_array_new_specific (MonoVTable *vtable, mono_array_size_t n)
+mono_array_new_specific (MonoVTable *vtable, uintptr_t n)
{
MonoObject *o;
MonoArray *ao;
- guint32 byte_len;
+ uintptr_t byte_len;
MONO_ARCH_SAVE_REGS;
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 (image->dynamic) {
MonoString *str = mono_lookup_dynamic_token (image, MONO_TOKEN_STRING | idx, NULL);
- if (mono_profiler_events & MONO_PROFILE_STRING_ALLOC)
- mono_profiler_string_allocation (domain, str);
return str;
} else {
if (!mono_verifier_verify_string_signature (image, idx, NULL))
mono_g_hash_table_insert (domain->ldstr_table, o, o);
ldstr_unlock ();
- if (mono_profiler_events & MONO_PROFILE_STRING_ALLOC)
- mono_profiler_string_allocation (domain, o);
-
return o;
}
* This is a temporary helper until our string implementation
* is reworked to always include the null terminating char.
*/
-gunichar2 *
+mono_unichar2*
mono_string_to_utf16 (MonoString *s)
{
char *as;
return callbacks.get_addr_from_ftnptr (descr);
}
-#if 0
/**
* mono_string_chars:
* @s: a MonoString
* Returns a pointer to the UCS16 characters stored in the MonoString
*/
gunichar2 *
-mono_string_chars(MonoString *s)
+mono_string_chars (MonoString *s)
{
- /* This method is here only for documentation extraction, this is a macro */
+ return s->chars;
}
/**
int
mono_string_length (MonoString *s)
{
- /* This method is here only for documentation extraction, this is a macro */
+ return s->length;
+}
+
+/**
+ * mono_array_length:
+ * @array: a MonoArray*
+ *
+ * Returns the total number of elements in the array. This works for
+ * both vectors and multidimensional arrays.
+ */
+uintptr_t
+mono_array_length (MonoArray *array)
+{
+ return array->max_length;
+}
+
+/**
+ * mono_array_addr_with_size:
+ * @array: a MonoArray*
+ * @size: size of the array elements
+ * @idx: index into the array
+ *
+ * Returns the address of the @idx element in the array.
+ */
+char*
+mono_array_addr_with_size (MonoArray *array, int size, uintptr_t idx)
+{
+ return ((char*)(array)->vector) + size * idx;
}
-#endif