2010-05-29 Robert Jordan <robertj@gmx.net>
[mono.git] / mono / metadata / object.c
index bd079f61d4f31b60b3bdfe112d1e06ea89c7ce9d..11043d598276bfce9d4ae0587376a3276f4de7fa 100644 (file)
@@ -633,6 +633,15 @@ compute_class_bitmap (MonoClass *class, gsize *bitmap, int size, int offset, int
                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))) {
@@ -1910,11 +1919,29 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class, gboolean
                        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 ().
@@ -2081,7 +2108,11 @@ mono_class_proxy_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, Mono
        MonoClass *class = remote_class->proxy_class;
        gpointer *interface_offsets;
        uint8_t *bitmap;
-       int bsize, bcsize;
+       int bsize;
+       
+#ifdef COMPRESSED_INTERFACE_BITMAP
+       int bcsize;
+#endif
 
        vt = mono_class_vtable (domain, class);
        g_assert (vt); /*FIXME property handle failure*/
@@ -2927,6 +2958,8 @@ mono_field_get_value (MonoObject *obj, MonoClassField *field, void *value)
 {
        void *src;
 
+       g_assert (obj);
+
        g_return_if_fail (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC));
 
        src = (char*)obj + field->offset;
@@ -2952,6 +2985,7 @@ mono_field_get_value_object (MonoDomain *domain, MonoClassField *field, MonoObje
        gchar *v;
        gboolean is_static = FALSE;
        gboolean is_ref = FALSE;
+       gboolean is_literal = FALSE;
 
        switch (field->type->type) {
        case MONO_TYPE_STRING:
@@ -2979,7 +3013,7 @@ mono_field_get_value_object (MonoDomain *domain, MonoClassField *field, MonoObje
                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 "
@@ -2987,21 +3021,32 @@ mono_field_get_value_object (MonoDomain *domain, MonoClassField *field, MonoObje
                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);
@@ -3017,7 +3062,10 @@ mono_field_get_value_object (MonoDomain *domain, MonoClassField *field, MonoObje
 
        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);
@@ -3697,7 +3745,12 @@ mono_unhandled_exception (MonoObject *exc)
        }
 }
 
-/*
+/**
+ * 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
@@ -3965,6 +4018,7 @@ mono_runtime_invoke_array (MonoMethod *method, void *obj, MonoArray *params,
 
                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]);
                        }