[runtime] Introduce kind test functions to cleanup things a bit.
[mono.git] / mono / metadata / object.c
index 16571fd270f88715d29ab70282e3fab650096aac..c60d9d3f4e20c9fd4f39c98fc513be27405ac0c3 100644 (file)
@@ -1406,7 +1406,7 @@ build_imt_slots (MonoClass *klass, MonoVTable *vt, MonoDomain *domain, gpointer*
                for (method_slot_in_interface = 0; method_slot_in_interface < iface->method.count; method_slot_in_interface++) {
                        MonoMethod *method;
 
-                       if (slot_num >= 0 && iface->is_inflated) {
+                       if (slot_num >= 0 && mono_class_is_ginst (iface)) {
                                /*
                                 * The imt slot of the method is the same as for its declaring method,
                                 * see the comment in mono_method_get_imt_slot (), so we can
@@ -1562,49 +1562,8 @@ mono_vtable_build_imt_slot (MonoVTable* vtable, int imt_slot)
        mono_loader_unlock ();
 }
 
-
-/*
- * The first two free list entries both belong to the wait list: The
- * first entry is the pointer to the head of the list and the second
- * entry points to the last element.  That way appending and removing
- * the first element are both O(1) operations.
- */
-#ifdef MONO_SMALL_CONFIG
-#define NUM_FREE_LISTS         6
-#else
-#define NUM_FREE_LISTS         12
-#endif
-#define FIRST_FREE_LIST_SIZE   64
-#define MAX_WAIT_LENGTH        50
 #define THUNK_THRESHOLD                10
 
-/*
- * LOCKING: The domain lock must be held.
- */
-static void
-init_thunk_free_lists (MonoDomain *domain)
-{
-       MONO_REQ_GC_NEUTRAL_MODE;
-
-       if (domain->thunk_free_lists)
-               return;
-       domain->thunk_free_lists = (MonoThunkFreeList **)mono_domain_alloc0 (domain, sizeof (gpointer) * NUM_FREE_LISTS);
-}
-
-static int
-list_index_for_size (int item_size)
-{
-       int i = 2;
-       int size = FIRST_FREE_LIST_SIZE;
-
-       while (item_size > size && i < NUM_FREE_LISTS - 1) {
-               i++;
-               size <<= 1;
-       }
-
-       return i;
-}
-
 /**
  * mono_method_alloc_generic_virtual_trampoline:
  * @domain: a domain
@@ -1624,36 +1583,6 @@ mono_method_alloc_generic_virtual_trampoline (MonoDomain *domain, int size)
        static gboolean inited = FALSE;
        static int generic_virtual_trampolines_size = 0;
 
-       guint32 *p;
-       int i;
-       MonoThunkFreeList **l;
-
-       init_thunk_free_lists (domain);
-
-       size += sizeof (guint32);
-       if (size < sizeof (MonoThunkFreeList))
-               size = sizeof (MonoThunkFreeList);
-
-       i = list_index_for_size (size);
-       for (l = &domain->thunk_free_lists [i]; *l; l = &(*l)->next) {
-               if ((*l)->size >= size) {
-                       MonoThunkFreeList *item = *l;
-                       *l = item->next;
-                       return ((guint32*)item) + 1;
-               }
-       }
-
-       /* no suitable item found - search lists of larger sizes */
-       while (++i < NUM_FREE_LISTS) {
-               MonoThunkFreeList *item = domain->thunk_free_lists [i];
-               if (!item)
-                       continue;
-               g_assert (item->size > size);
-               domain->thunk_free_lists [i] = item->next;
-               return ((guint32*)item) + 1;
-       }
-
-       /* still nothing found - allocate it */
        if (!inited) {
                mono_counters_register ("Generic virtual trampoline bytes",
                                MONO_COUNTER_GENERICS | MONO_COUNTER_INT, &generic_virtual_trampolines_size);
@@ -1661,68 +1590,7 @@ mono_method_alloc_generic_virtual_trampoline (MonoDomain *domain, int size)
        }
        generic_virtual_trampolines_size += size;
 
-       p = (guint32 *)mono_domain_code_reserve (domain, size);
-       *p = size;
-
-       mono_domain_lock (domain);
-       if (!domain->generic_virtual_trampolines)
-               domain->generic_virtual_trampolines = g_hash_table_new (NULL, NULL);
-       g_hash_table_insert (domain->generic_virtual_trampolines, p, p);
-       mono_domain_unlock (domain);
-
-       return p + 1;
-}
-
-/*
- * LOCKING: The domain lock must be held.
- */
-static void
-invalidate_generic_virtual_trampoline (MonoDomain *domain, gpointer code)
-{
-       MONO_REQ_GC_NEUTRAL_MODE;
-
-       guint32 *p = (guint32 *)code;
-       MonoThunkFreeList *l = (MonoThunkFreeList*)(p - 1);
-       gboolean found = FALSE;
-
-       mono_domain_lock (domain);
-       if (!domain->generic_virtual_trampolines)
-               domain->generic_virtual_trampolines = g_hash_table_new (NULL, NULL);
-       if (g_hash_table_lookup (domain->generic_virtual_trampolines, l))
-               found = TRUE;
-       mono_domain_unlock (domain);
-
-       if (!found)
-               /* Not allocated by mono_method_alloc_generic_virtual_trampoline (), i.e. AOT */
-               return;
-       init_thunk_free_lists (domain);
-
-       while (domain->thunk_free_lists [0] && domain->thunk_free_lists [0]->length >= MAX_WAIT_LENGTH) {
-               MonoThunkFreeList *item = domain->thunk_free_lists [0];
-               int length = item->length;
-               int i;
-
-               /* unlink the first item from the wait list */
-               domain->thunk_free_lists [0] = item->next;
-               domain->thunk_free_lists [0]->length = length - 1;
-
-               i = list_index_for_size (item->size);
-
-               /* put it in the free list */
-               item->next = domain->thunk_free_lists [i];
-               domain->thunk_free_lists [i] = item;
-       }
-
-       l->next = NULL;
-       if (domain->thunk_free_lists [1]) {
-               domain->thunk_free_lists [1] = domain->thunk_free_lists [1]->next = l;
-               domain->thunk_free_lists [0]->length++;
-       } else {
-               g_assert (!domain->thunk_free_lists [0]);
-
-               domain->thunk_free_lists [0] = domain->thunk_free_lists [1] = l;
-               domain->thunk_free_lists [0]->length = 1;
-       }
+       return mono_domain_code_reserve (domain, size);
 }
 
 typedef struct _GenericVirtualCase {
@@ -1797,6 +1665,7 @@ mono_method_add_generic_virtual_invocation (MonoDomain *domain, MonoVTable *vtab
 
        static gboolean inited = FALSE;
        static int num_added = 0;
+       static int num_freed = 0;
 
        GenericVirtualCase *gvc, *list;
        MonoImtBuilderEntry *entries;
@@ -1807,6 +1676,12 @@ mono_method_add_generic_virtual_invocation (MonoDomain *domain, MonoVTable *vtab
        if (!domain->generic_virtual_cases)
                domain->generic_virtual_cases = g_hash_table_new (mono_aligned_addr_hash, NULL);
 
+       if (!inited) {
+               mono_counters_register ("Generic virtual cases", MONO_COUNTER_GENERICS | MONO_COUNTER_INT, &num_added);
+               mono_counters_register ("Freed IMT trampolines", MONO_COUNTER_GENERICS | MONO_COUNTER_INT, &num_freed);
+               inited = TRUE;
+       }
+
        /* Check whether the case was already added */
        list = (GenericVirtualCase *)g_hash_table_lookup (domain->generic_virtual_cases, vtable_slot);
        gvc = list;
@@ -1826,10 +1701,6 @@ mono_method_add_generic_virtual_invocation (MonoDomain *domain, MonoVTable *vtab
 
                g_hash_table_insert (domain->generic_virtual_cases, vtable_slot, gvc);
 
-               if (!inited) {
-                       mono_counters_register ("Generic virtual cases", MONO_COUNTER_GENERICS | MONO_COUNTER_INT, &num_added);
-                       inited = TRUE;
-               }
                num_added++;
        }
 
@@ -1864,14 +1735,10 @@ mono_method_add_generic_virtual_invocation (MonoDomain *domain, MonoVTable *vtab
                        for (i = 0; i < sorted->len; ++i)
                                g_free (g_ptr_array_index (sorted, i));
                        g_ptr_array_free (sorted, TRUE);
-               }
 
-#ifndef __native_client__
-               /* We don't re-use any trampolines as there is a lot of overhead */
-               /* to deleting and re-using code in Native Client.          */
-               if (old_thunk != vtable_trampoline && old_thunk != imt_trampoline)
-                       invalidate_generic_virtual_trampoline (domain, old_thunk);
-#endif
+                       if (old_thunk != vtable_trampoline && old_thunk != imt_trampoline)
+                               num_freed ++;
+               }
        }
 
        mono_domain_unlock (domain);
@@ -2023,7 +1890,7 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *klass, MonoErro
                if (mono_class_has_failure (element_class)) {
                        /*Can happen if element_class only got bad after mono_class_setup_vtable*/
                        if (!mono_class_has_failure (klass))
-                               mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+                               mono_class_set_type_load_failure (klass, "");
                        mono_domain_unlock (domain);
                        mono_loader_unlock ();
                        mono_error_set_for_class_failure (error, klass);
@@ -3878,7 +3745,7 @@ mono_nullable_init (guint8 *buf, MonoObject *value, MonoClass *klass)
 
        MonoClass *param_class = klass->cast_class;
 
-       mono_class_setup_fields_locking (klass);
+       mono_class_setup_fields (klass);
        g_assert (klass->fields_inited);
                                
        g_assert (mono_class_from_mono_type (klass->fields [0].type) == param_class);
@@ -3912,7 +3779,7 @@ mono_nullable_box (guint8 *buf, MonoClass *klass, MonoError *error)
        mono_error_init (error);
        MonoClass *param_class = klass->cast_class;
 
-       mono_class_setup_fields_locking (klass);
+       mono_class_setup_fields (klass);
        g_assert (klass->fields_inited);
 
        g_assert (mono_class_from_mono_type (klass->fields [0].type) == param_class);
@@ -5590,7 +5457,7 @@ mono_class_get_allocation_ftn (MonoVTable *vtable, gboolean for_box, gboolean *p
 
        *pass_size_in_words = FALSE;
 
-       if (mono_class_has_finalizer (vtable->klass) || mono_class_is_marshalbyref (vtable->klass) || (mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS))
+       if (mono_class_has_finalizer (vtable->klass) || mono_class_is_marshalbyref (vtable->klass))
                return ves_icall_object_new_specific;
 
        if (vtable->gc_descr != MONO_GC_DESCRIPTOR_NULL) {
@@ -5955,7 +5822,7 @@ mono_array_new_full_checked (MonoDomain *domain, MonoClass *array_class, uintptr
                o = (MonoObject *)mono_gc_alloc_vector (vtable, byte_len, len);
 
        if (G_UNLIKELY (!o)) {
-               mono_error_set_out_of_memory (error, "Could not allocate %i bytes", byte_len);
+               mono_error_set_out_of_memory (error, "Could not allocate %zd bytes", (gsize) byte_len);
                return NULL;
        }
 
@@ -6069,7 +5936,7 @@ mono_array_new_specific_checked (MonoVTable *vtable, uintptr_t n, MonoError *err
        o = (MonoObject *)mono_gc_alloc_vector (vtable, byte_len, n);
 
        if (G_UNLIKELY (!o)) {
-               mono_error_set_out_of_memory (error, "Could not allocate %i bytes", byte_len);
+               mono_error_set_out_of_memory (error, "Could not allocate %zd bytes", (gsize) byte_len);
                return NULL;
        }
 
@@ -6227,7 +6094,7 @@ mono_string_new_size_checked (MonoDomain *domain, gint32 len, MonoError *error)
        s = (MonoString *)mono_gc_alloc_string (vtable, size, len);
 
        if (G_UNLIKELY (!s)) {
-               mono_error_set_out_of_memory (error, "Could not allocate %i bytes", size);
+               mono_error_set_out_of_memory (error, "Could not allocate %zd bytes", size);
                return NULL;
        }