#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
*
#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);
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 */
#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
}
#endif
-static char *dump_prefix = NULL;
-
static void
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)
{
for (j = 0; j < api_sccs [i]->num_objs; ++j) {
GCVTable vtable = SGEN_LOAD_VTABLE (api_sccs [i]->objs [j]);
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_GC,
- "OBJECT %s (%p) SCC [%d] %s",
+ "OBJECT %s.%s (%p) SCC [%d] %s",
sgen_client_vtable_get_namespace (vtable), sgen_client_vtable_get_name (vtable), api_sccs [i]->objs [j],
i,
api_sccs [i]->is_alive ? "ALIVE" : "DEAD");
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;
}