Merge pull request #3528 from BrzVlad/fix-sgen-check-before-collections
[mono.git] / mono / metadata / sgen-new-bridge.c
index a1eb82a714fcdbfa72a89003e1eb988869f8a0b9..501ceb76d5b8c5a987d26b28891e01ca701cdb53 100644 (file)
 #include "tabledefs.h"
 #include "utils/mono-logger-internals.h"
 
+#define OPTIMIZATION_COPY
+#define OPTIMIZATION_FORWARD
+#define OPTIMIZATION_SINGLETON_DYN_ARRAY
+#include "sgen-dynarray.h"
+
 //#define NEW_XREFS
 #ifdef NEW_XREFS
 //#define TEST_NEW_XREFS
 #define XREFS old_xrefs
 #endif
 
-#define OPTIMIZATION_COPY
-#define OPTIMIZATION_FORWARD
-#define OPTIMIZATION_SINGLETON_DYN_ARRAY
-
-typedef struct {
-       int size;
-       int capacity;           /* if negative, data points to another DynArray's data */
-       char *data;
-} DynArray;
-
-/*Specializations*/
-
-typedef struct {
-       DynArray array;
-} DynIntArray;
-
-typedef struct {
-       DynArray array;
-} DynPtrArray;
-
-typedef struct {
-       DynArray array;
-} DynSCCArray;
-
-
 /*
  * Bridge data for a single managed object
  *
@@ -121,6 +101,8 @@ typedef struct _SCC {
 #endif
 } SCC;
 
+static char *dump_prefix = NULL;
+
 // Maps managed objects to corresponding HashEntry stricts
 static SgenHashTable hash_table = SGEN_HASH_TABLE_INIT (INTERNAL_MEM_BRIDGE_HASH_TABLE, INTERNAL_MEM_BRIDGE_HASH_TABLE_ENTRY, sizeof (HashEntry), mono_aligned_addr_hash, NULL);
 
@@ -131,266 +113,6 @@ static gboolean bridge_accounting_enabled = FALSE;
 static SgenBridgeProcessor *bridge_processor;
 
 /* Core functions */
-/* public */
-
-/* private */
-
-static void
-dyn_array_init (DynArray *da)
-{
-       da->size = 0;
-       da->capacity = 0;
-       da->data = NULL;
-}
-
-static void
-dyn_array_uninit (DynArray *da, int elem_size)
-{
-       if (da->capacity < 0) {
-               dyn_array_init (da);
-               return;
-       }
-
-       if (da->capacity == 0)
-               return;
-
-       sgen_free_internal_dynamic (da->data, elem_size * da->capacity, INTERNAL_MEM_BRIDGE_DATA);
-       da->data = NULL;
-}
-
-static void
-dyn_array_empty (DynArray *da)
-{
-       if (da->capacity < 0)
-               dyn_array_init (da);
-       else
-               da->size = 0;
-}
-
-static void
-dyn_array_ensure_capacity (DynArray *da, int capacity, int elem_size)
-{
-       int old_capacity = da->capacity;
-       char *new_data;
-
-       g_assert (capacity > 0);
-
-       if (capacity <= old_capacity)
-               return;
-
-       if (old_capacity <= 0)
-               da->capacity = 2;
-       while (capacity > da->capacity)
-               da->capacity *= 2;
-
-       new_data = (char *)sgen_alloc_internal_dynamic (elem_size * da->capacity, INTERNAL_MEM_BRIDGE_DATA, TRUE);
-       memcpy (new_data, da->data, elem_size * da->size);
-       if (old_capacity > 0)
-               sgen_free_internal_dynamic (da->data, elem_size * old_capacity, INTERNAL_MEM_BRIDGE_DATA);
-       da->data = new_data;
-}
-
-static gboolean
-dyn_array_is_copy (DynArray *da)
-{
-       return da->capacity < 0;
-}
-
-static void
-dyn_array_ensure_independent (DynArray *da, int elem_size)
-{
-       if (!dyn_array_is_copy (da))
-               return;
-       dyn_array_ensure_capacity (da, da->size, elem_size);
-       g_assert (da->capacity > 0);
-}
-
-static void*
-dyn_array_add (DynArray *da, int elem_size)
-{
-       void *p;
-
-       dyn_array_ensure_capacity (da, da->size + 1, elem_size);
-
-       p = da->data + da->size * elem_size;
-       ++da->size;
-       return p;
-}
-
-static void
-dyn_array_copy (DynArray *dst, DynArray *src, int elem_size)
-{
-       dyn_array_uninit (dst, elem_size);
-
-       if (src->size == 0)
-               return;
-
-       dst->size = src->size;
-       dst->capacity = -1;
-       dst->data = src->data;
-}
-
-/* int */
-static void
-dyn_array_int_init (DynIntArray *da)
-{
-       dyn_array_init (&da->array);
-}
-
-static void
-dyn_array_int_uninit (DynIntArray *da)
-{
-       dyn_array_uninit (&da->array, sizeof (int));
-}
-
-static int
-dyn_array_int_size (DynIntArray *da)
-{
-       return da->array.size;
-}
-
-#ifdef NEW_XREFS
-static void
-dyn_array_int_empty (DynIntArray *da)
-{
-       dyn_array_empty (&da->array);
-}
-#endif
-
-static void
-dyn_array_int_add (DynIntArray *da, int x)
-{
-       int *p = (int *)dyn_array_add (&da->array, sizeof (int));
-       *p = x;
-}
-
-static int
-dyn_array_int_get (DynIntArray *da, int x)
-{
-       return ((int*)da->array.data)[x];
-}
-
-#ifdef NEW_XREFS
-static void
-dyn_array_int_set (DynIntArray *da, int idx, int val)
-{
-       ((int*)da->array.data)[idx] = val;
-}
-#endif
-
-static void
-dyn_array_int_ensure_independent (DynIntArray *da)
-{
-       dyn_array_ensure_independent (&da->array, sizeof (int));
-}
-
-static void
-dyn_array_int_copy (DynIntArray *dst, DynIntArray *src)
-{
-       dyn_array_copy (&dst->array, &src->array, sizeof (int));
-}
-
-static gboolean
-dyn_array_int_is_copy (DynIntArray *da)
-{
-       return dyn_array_is_copy (&da->array);
-}
-
-/* ptr */
-
-static void
-dyn_array_ptr_init (DynPtrArray *da)
-{
-       dyn_array_init (&da->array);
-}
-
-static void
-dyn_array_ptr_uninit (DynPtrArray *da)
-{
-#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
-       if (da->array.capacity == 1)
-               dyn_array_ptr_init (da);
-       else
-#endif
-               dyn_array_uninit (&da->array, sizeof (void*));
-}
-
-static int
-dyn_array_ptr_size (DynPtrArray *da)
-{
-       return da->array.size;
-}
-
-static void
-dyn_array_ptr_empty (DynPtrArray *da)
-{
-#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
-       if (da->array.capacity == 1)
-               dyn_array_ptr_init (da);
-       else
-#endif
-               dyn_array_empty (&da->array);
-}
-
-static void*
-dyn_array_ptr_get (DynPtrArray *da, int x)
-{
-#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
-       if (da->array.capacity == 1) {
-               g_assert (x == 0);
-               return da->array.data;
-       }
-#endif
-       return ((void**)da->array.data)[x];
-}
-
-static void
-dyn_array_ptr_add (DynPtrArray *da, void *ptr)
-{
-       void **p;
-
-#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
-       if (da->array.capacity == 0) {
-               da->array.capacity = 1;
-               da->array.size = 1;
-               p = (void**)&da->array.data;
-       } else if (da->array.capacity == 1) {
-               void *ptr0 = da->array.data;
-               void **p0;
-               dyn_array_init (&da->array);
-               p0 = (void **)dyn_array_add (&da->array, sizeof (void*));
-               *p0 = ptr0;
-               p = (void **)dyn_array_add (&da->array, sizeof (void*));
-       } else
-#endif
-       {
-               p = (void **)dyn_array_add (&da->array, sizeof (void*));
-       }
-       *p = ptr;
-}
-
-#define dyn_array_ptr_push dyn_array_ptr_add
-
-static void*
-dyn_array_ptr_pop (DynPtrArray *da)
-{
-       int size = da->array.size;
-       void *p;
-       g_assert (size > 0);
-#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
-       if (da->array.capacity == 1) {
-               p = dyn_array_ptr_get (da, 0);
-               dyn_array_init (&da->array);
-       } else
-#endif
-       {
-               g_assert (da->array.capacity > 1);
-               dyn_array_ensure_independent (&da->array, sizeof (void*));
-               p = dyn_array_ptr_get (da, size - 1);
-               --da->array.size;
-       }
-       return p;
-}
 
 /*SCC */
 
@@ -441,11 +163,16 @@ dyn_array_int_contains (DynIntArray *da, int x)
 #endif
 
 static void
-enable_accounting (void)
+set_config (const SgenBridgeProcessorConfig *config)
 {
-       SgenHashTable table = SGEN_HASH_TABLE_INIT (INTERNAL_MEM_BRIDGE_HASH_TABLE, INTERNAL_MEM_BRIDGE_HASH_TABLE_ENTRY, sizeof (HashEntryWithAccounting), mono_aligned_addr_hash, NULL);
-       bridge_accounting_enabled = TRUE;
-       hash_table = table;
+       if (config->accounting) {
+               SgenHashTable table = SGEN_HASH_TABLE_INIT (INTERNAL_MEM_BRIDGE_HASH_TABLE, INTERNAL_MEM_BRIDGE_HASH_TABLE_ENTRY, sizeof (HashEntryWithAccounting), mono_aligned_addr_hash, NULL);
+               bridge_accounting_enabled = TRUE;
+               hash_table = table;
+       }
+       if (config->dump_prefix) {
+               dump_prefix = strdup (config->dump_prefix);
+       }
 }
 
 static MonoGCBridgeObjectKind
@@ -884,8 +611,6 @@ reset_flags (SCC *scc)
 }
 #endif
 
-static char *dump_prefix = NULL;
-
 static void
 dump_graph (void)
 {
@@ -937,12 +662,6 @@ dump_graph (void)
        fclose (file);
 }
 
-static void
-set_dump_prefix (const char *prefix)
-{
-       dump_prefix = strdup (prefix);
-}
-
 static int
 compare_hash_entries (const HashEntry *e1, const HashEntry *e2)
 {
@@ -1367,8 +1086,7 @@ sgen_new_bridge_init (SgenBridgeProcessor *collector)
        collector->class_kind = class_kind;
        collector->register_finalized_object = register_finalized_object;
        collector->describe_pointer = describe_pointer;
-       collector->enable_accounting = enable_accounting;
-       collector->set_dump_prefix = set_dump_prefix;
+       collector->set_config = set_config;
 
        bridge_processor = collector;
 }