#include <mono/io-layer/io-layer.h>
#include "mono/utils/mono-compiler.h"
#include "mono/utils/mono-error.h"
+#include "mono/sgen/gc-internal-agnostic.h"
#define MONO_CLASS_IS_ARRAY(c) ((c)->rank)
MonoGenericClass *generic_class;
MonoGenericContainer *generic_container;
- void *gc_descr;
+ MonoGCDescriptor gc_descr;
MonoClassRuntimeInfo *runtime_info;
* According to comments in gc_gcj.h, this should be the second word in
* the vtable.
*/
- void *gc_descr;
+ MonoGCDescriptor gc_descr;
MonoDomain *domain; /* each object/vtable belongs to exactly one domain */
gpointer type; /* System.Type type for klass */
guint8 *interface_bitmap;
int id = -1, i;
if (!appdomains_list) {
appdomain_list_size = 2;
- appdomains_list = mono_gc_alloc_fixed (appdomain_list_size * sizeof (void*), NULL);
+ appdomains_list = mono_gc_alloc_fixed (appdomain_list_size * sizeof (void*), MONO_GC_DESCRIPTOR_NULL);
}
for (i = appdomain_next; i < appdomain_list_size; ++i) {
if (!appdomains_list [i]) {
if (new_size >= (1 << 16))
g_assert_not_reached ();
id = appdomain_list_size;
- new_list = mono_gc_alloc_fixed (new_size * sizeof (void*), NULL);
+ new_list = mono_gc_alloc_fixed (new_size * sizeof (void*), MONO_GC_DESCRIPTOR_NULL);
memcpy (new_list, appdomains_list, appdomain_list_size * sizeof (void*));
mono_gc_free_fixed (appdomains_list);
appdomains_list = new_list;
}
static gsize domain_gc_bitmap [sizeof(MonoDomain)/4/32 + 1];
-static gpointer domain_gc_desc = NULL;
+static MonoGCDescriptor domain_gc_desc = MONO_GC_DESCRIPTOR_NULL;
static guint32 domain_shadow_serial = 0L;
MonoDomain *
domain = mono_gc_alloc_fixed (sizeof (MonoDomain), NULL);
#else
domain = mono_gc_alloc_fixed (sizeof (MonoDomain), domain_gc_desc);
- mono_gc_register_root ((char*)&(domain->MONO_DOMAIN_FIRST_GC_TRACKED), G_STRUCT_OFFSET (MonoDomain, MONO_DOMAIN_LAST_GC_TRACKED) - G_STRUCT_OFFSET (MonoDomain, MONO_DOMAIN_FIRST_GC_TRACKED), NULL);
+ mono_gc_register_root ((char*)&(domain->MONO_DOMAIN_FIRST_GC_TRACKED), G_STRUCT_OFFSET (MonoDomain, MONO_DOMAIN_LAST_GC_TRACKED) - G_STRUCT_OFFSET (MonoDomain, MONO_DOMAIN_FIRST_GC_TRACKED), MONO_GC_DESCRIPTOR_NULL);
#endif
domain->shadow_serial = shadow_serial;
domain->domain = NULL;
*/
mono_appdomains_lock ();
size = appdomain_list_size;
- copy = mono_gc_alloc_fixed (appdomain_list_size * sizeof (void*), NULL);
+ copy = mono_gc_alloc_fixed (appdomain_list_size * sizeof (void*), MONO_GC_DESCRIPTOR_NULL);
memcpy (copy, appdomains_list, appdomain_list_size * sizeof (void*));
mono_appdomains_unlock ();
#define mono_domain_finalizers_unlock(domain) mono_mutex_unlock (&(domain)->finalizable_objects_hash_lock);
/* Register a memory area as a conservatively scanned GC root */
-#define MONO_GC_REGISTER_ROOT_PINNING(x) mono_gc_register_root ((char*)&(x), sizeof(x), NULL)
+#define MONO_GC_REGISTER_ROOT_PINNING(x) mono_gc_register_root ((char*)&(x), sizeof(x), MONO_GC_DESCRIPTOR_NULL)
#define MONO_GC_UNREGISTER_ROOT(x) mono_gc_deregister_root ((char*)&(x))
* by mono_gc_alloc_fixed ().
*/
/* For SGEN, the result of alloc_fixed () is not GC tracked memory */
-#define MONO_GC_ROOT_DESCR_FOR_FIXED(n) (mono_gc_is_moving () ? mono_gc_make_root_descr_all_refs (0) : NULL)
+#define MONO_GC_ROOT_DESCR_FOR_FIXED(n) (mono_gc_is_moving () ? mono_gc_make_root_descr_all_refs (0) : MONO_GC_DESCRIPTOR_NULL)
/* Register a memory location holding a single object reference as a GC root */
#define MONO_GC_REGISTER_ROOT_SINGLE(x) do { \
* foreach (ref in GC references in the are structure pointed to by ADDR)
* mark_func (ref)
*/
-typedef void (*MonoGCMarkFunc) (void **addr, void *gc_data);
+typedef void (*MonoGCMarkFunc) (MonoObject **addr, void *gc_data);
typedef void (*MonoGCRootMarkFunc) (void *addr, MonoGCMarkFunc mark_func, void *gc_data);
/* Create a descriptor with a user defined marking function */
-void *mono_gc_make_root_descr_user (MonoGCRootMarkFunc marker);
+MonoGCDescriptor mono_gc_make_root_descr_user (MonoGCRootMarkFunc marker);
/* Return whenever user defined marking functions are supported */
gboolean mono_gc_user_markers_supported (void);
* NOTE: Under Boehm, this returns memory allocated using GC_malloc, so the result should
* be stored into a location registered using MONO_GC_REGISTER_ROOT_FIXED ().
*/
-void* mono_gc_alloc_fixed (size_t size, void *descr);
+void* mono_gc_alloc_fixed (size_t size, MonoGCDescriptor descr);
void mono_gc_free_fixed (void* addr);
/* make sure the gchandle was allocated for an object in domain */
void* mono_gc_alloc_vector (MonoVTable *vtable, size_t size, uintptr_t max_length);
void* mono_gc_alloc_array (MonoVTable *vtable, size_t size, uintptr_t max_length, uintptr_t bounds_size);
void* mono_gc_alloc_string (MonoVTable *vtable, size_t size, gint32 len);
-void* mono_gc_make_descr_for_string (gsize *bitmap, int numbits);
+MonoGCDescriptor mono_gc_make_descr_for_string (gsize *bitmap, int numbits);
void mono_gc_register_for_finalization (MonoObject *obj, void *user_data);
void mono_gc_add_memory_pressure (gint64 value);
-MONO_API int mono_gc_register_root (char *start, size_t size, void *descr);
+MONO_API int mono_gc_register_root (char *start, size_t size, MonoGCDescriptor descr);
void mono_gc_deregister_root (char* addr);
int mono_gc_finalizers_for_domain (MonoDomain *domain, MonoObject **out_array, int out_size);
void mono_gc_run_finalize (void *obj, void *data);
* FIXME: Add an API for clearing remset entries if a root with a user defined
* mark routine is deleted.
*/
-int mono_gc_register_root_wbarrier (char *start, size_t size, void *descr);
+int mono_gc_register_root_wbarrier (char *start, size_t size, MonoGCDescriptor descr);
void mono_gc_wbarrier_set_root (gpointer ptr, MonoObject *value);
return -1;
}
-static void*
+static MonoGCDescriptor
make_root_descr_all_refs (int numbits, gboolean pinned)
{
#ifdef HAVE_SGEN_GC
if (pinned)
- return NULL;
+ return MONO_GC_DESCRIPTOR_NULL;
#endif
return mono_gc_make_root_descr_all_refs (numbits);
}
typedef struct _Slot Slot;
struct _Slot {
- gpointer key;
- gpointer value;
+ MonoObject *key;
+ MonoObject *value;
Slot *next;
};
};
#ifdef HAVE_SGEN_GC
-static void *table_hash_descr = NULL;
+static MonoGCDescriptor table_hash_descr = MONO_GC_DESCRIPTOR_NULL;
static void mono_g_hash_mark (void *addr, MonoGCMarkFunc mark_func, void *gc_data);
new_slot (MonoGHashTable *hash)
{
if (hash->gc_type == MONO_HASH_CONSERVATIVE_GC)
- return mono_gc_alloc_fixed (sizeof (Slot), NULL);
+ return mono_gc_alloc_fixed (sizeof (Slot), MONO_GC_DESCRIPTOR_NULL);
else
return mg_new (Slot, 1);
}
#include <mono/utils/mono-memory-model.h>
#include "cominterop.h"
-#if defined(HAVE_BOEHM_GC)
-#define GC_NO_DESCRIPTOR ((gpointer)(0 | GC_DS_LENGTH))
-#elif defined(HAVE_SGEN_GC)
-#define GC_NO_DESCRIPTOR (NULL)
-#else
-#define GC_NO_DESCRIPTOR (NULL)
-#endif
-
static void
get_default_field_value (MonoDomain* domain, MonoClassField *field, void *value);
return;
class->gc_descr_inited = TRUE;
- class->gc_descr = GC_NO_DESCRIPTOR;
+ class->gc_descr = MONO_GC_DESCRIPTOR_NULL;
bitmap = default_bitmap;
if (class == mono_defaults.string_class) {
- class->gc_descr = (gpointer)mono_gc_make_descr_for_string (bitmap, 2);
+ class->gc_descr = mono_gc_make_descr_for_string (bitmap, 2);
} else if (class->rank) {
mono_class_compute_gc_descriptor (class->element_class);
if (MONO_TYPE_IS_REFERENCE (&class->element_class->byval_arg)) {
if (count++ > 58)
return;*/
bitmap = compute_class_bitmap (class, default_bitmap, sizeof (default_bitmap) * 8, 0, &max_set, FALSE);
- class->gc_descr = (gpointer)mono_gc_make_descr_for_object (bitmap, max_set + 1, class->instance_size);
+ class->gc_descr = mono_gc_make_descr_for_object (bitmap, max_set + 1, class->instance_size);
/*
- if (class->gc_descr == GC_NO_DESCRIPTOR)
+ if (class->gc_descr == MONO_GC_DESCRIPTOR_NULL)
g_print ("disabling typed alloc (%d) for %s.%s\n", max_set, class->name_space, class->name);
*/
/*printf ("new descriptor: %p 0x%x for %s.%s\n", class->gc_descr, bitmap [0], class->name_space, class->name);*/
*/
#ifdef HAVE_BOEHM_GC
if (domain != mono_get_root_domain () && !mono_dont_free_domains)
- vt->gc_descr = GC_NO_DESCRIPTOR;
+ vt->gc_descr = MONO_GC_DESCRIPTOR_NULL;
else
#endif
vt->gc_descr = class->gc_descr;
if (class_size) {
/* we store the static field pointer at the end of the vtable: vt->vtable [class->vtable_size] */
if (class->has_static_refs) {
- gpointer statics_gc_descr;
+ MonoGCDescriptor statics_gc_descr;
int max_set = 0;
gsize default_bitmap [4] = {0};
gsize *bitmap;
if (mono_class_has_finalizer (vtable->klass) || mono_class_is_marshalbyref (vtable->klass) || (mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS))
return mono_object_new_specific;
- if (vtable->gc_descr != GC_NO_DESCRIPTOR) {
+ if (vtable->gc_descr != MONO_GC_DESCRIPTOR_NULL) {
return mono_object_new_fast;
memset (params, 0, sizeof (void*) * sig->param_count);
} else {
/* Allocate using GC so it gets GC tracking */
- params = mono_gc_alloc_fixed (sig->param_count * sizeof (void*), NULL);
+ params = mono_gc_alloc_fixed (sig->param_count * sizeof (void*), MONO_GC_DESCRIPTOR_NULL);
}
/* skip prolog */
HEAVY_STAT (++stat_wbarrier_value_copy);
g_assert (klass->valuetype);
- SGEN_LOG (8, "Adding value remset at %p, count %d, descr %p for class %s (%p)", dest, count, klass->gc_descr, klass->name, klass);
+ SGEN_LOG (8, "Adding value remset at %p, count %d, descr %p for class %s (%p)", dest, count, (gpointer)klass->gc_descr, klass->name, klass);
if (sgen_ptr_in_nursery (dest) || ptr_on_stack (dest) || !sgen_gc_descr_has_references ((mword)klass->gc_descr)) {
size_t element_size = mono_class_value_size (klass, NULL);
}
void*
-mono_gc_alloc_fixed (size_t size, void *descr)
+mono_gc_alloc_fixed (size_t size, MonoGCDescriptor descr)
{
/* FIXME: do a single allocation */
void *res = calloc (1, size);
static GCRootReport *root_report;
static void
-single_arg_report_root (void **obj, void *gc_data)
+single_arg_report_root (MonoObject **obj, void *gc_data)
{
if (*obj)
add_profile_gc_root (root_report, *obj, MONO_PROFILE_GC_ROOT_OTHER, 0);
case ROOT_DESC_USER: {
MonoGCRootMarkFunc marker = (MonoGCRootMarkFunc)sgen_get_user_descriptor_func (desc);
root_report = report;
- marker (start_root, single_arg_report_root, NULL);
+ marker ((MonoObject**)start_root, single_arg_report_root, NULL);
break;
}
case ROOT_DESC_RUN_LEN:
*/
int
-mono_gc_register_root (char *start, size_t size, void *descr)
+mono_gc_register_root (char *start, size_t size, MonoGCDescriptor descr)
{
- return sgen_register_root (start, size, (SgenDescriptor)descr, descr ? ROOT_TYPE_NORMAL : ROOT_TYPE_PINNED);
+ return sgen_register_root (start, size, descr, descr ? ROOT_TYPE_NORMAL : ROOT_TYPE_PINNED);
}
int
-mono_gc_register_root_wbarrier (char *start, size_t size, void *descr)
+mono_gc_register_root_wbarrier (char *start, size_t size, MonoGCDescriptor descr)
{
- return sgen_register_root (start, size, (SgenDescriptor)descr, ROOT_TYPE_WBARRIER);
+ return sgen_register_root (start, size, descr, ROOT_TYPE_WBARRIER);
}
void
return (int64_t)sgen_gc_get_total_heap_allocation ();
}
-void*
+MonoGCDescriptor
mono_gc_make_root_descr_user (MonoGCRootMarkFunc marker)
{
- return (void*)sgen_make_user_root_descriptor ((SgenUserRootMarkFunc)marker);
+ return sgen_make_user_root_descriptor (marker);
}
-void*
+MonoGCDescriptor
mono_gc_make_descr_for_string (gsize *bitmap, int numbits)
{
- return (void*)SGEN_DESC_STRING;
+ return SGEN_DESC_STRING;
}
void*
void **p = ptr + idx;
if (*p)
- mark_func (p, gc_data);
+ mark_func ((MonoObject**)p, gc_data);
});
}
}
gpointer* static_data = *static_data_ptr;
if (!static_data) {
- static void *tls_desc = NULL;
- static void *ctx_desc = NULL;
+ static MonoGCDescriptor tls_desc = MONO_GC_DESCRIPTOR_NULL;
+ static MonoGCDescriptor ctx_desc = MONO_GC_DESCRIPTOR_NULL;
if (mono_gc_user_markers_supported ()) {
- if (!tls_desc)
+ if (tls_desc == MONO_GC_DESCRIPTOR_NULL)
tls_desc = mono_gc_make_root_descr_user (mark_tls_slots);
- if (!ctx_desc)
+ if (ctx_desc == MONO_GC_DESCRIPTOR_NULL)
ctx_desc = mono_gc_make_root_descr_user (mark_ctx_slots);
}
if (mono_gc_user_markers_supported ())
static_data [i] = g_malloc0 (static_data_size [i]);
else
- static_data [i] = mono_gc_alloc_fixed (static_data_size [i], NULL);
+ static_data [i] = mono_gc_alloc_fixed (static_data_size [i], MONO_GC_DESCRIPTOR_NULL);
}
}
#include "mono/utils/mono-compiler.h"
#include "mono/utils/parse.h"
#include "mono/utils/memfuncs.h"
+#ifdef HAVE_SGEN_GC
+#include "mono/sgen/sgen-conf.h"
+#endif
typedef struct {
guint minor_gc_count;
extern GCStats gc_stats;
+#ifdef HAVE_SGEN_GC
+typedef SgenDescriptor MonoGCDescriptor;
+#define MONO_GC_DESCRIPTOR_NULL SGEN_DESCRIPTOR_NULL
+#else
+typedef void* MonoGCDescriptor;
+#define MONO_GC_DESCRIPTOR_NULL NULL
+#endif
+
/*
* Try to register a foreign thread with the GC, if we fail or the backend
* can't cope with this concept - we return FALSE.
gboolean mono_gc_parse_environment_string_extract_number (const char *str, size_t *out);
-void* mono_gc_make_descr_for_object (gsize *bitmap, int numbits, size_t obj_size);
-void* mono_gc_make_descr_for_array (int vector, gsize *elem_bitmap, int numbits, size_t elem_size);
+MonoGCDescriptor mono_gc_make_descr_for_object (gsize *bitmap, int numbits, size_t obj_size);
+MonoGCDescriptor mono_gc_make_descr_for_array (int vector, gsize *elem_bitmap, int numbits, size_t elem_size);
/* simple interface for data structures needed in the runtime */
-void* mono_gc_make_descr_from_bitmap (gsize *bitmap, int numbits);
+MonoGCDescriptor mono_gc_make_descr_from_bitmap (gsize *bitmap, int numbits);
/* Return a root descriptor for a root with all refs */
-void* mono_gc_make_root_descr_all_refs (int numbits);
+MonoGCDescriptor mono_gc_make_root_descr_all_refs (int numbits);
/* Return the bitmap encoded by a descriptor */
-gsize* mono_gc_get_bitmap_for_descr (void *descr, int *numbits);
+gsize* mono_gc_get_bitmap_for_descr (MonoGCDescriptor descr, int *numbits);
/*
These functions must be used when it's possible that either destination is not
typedef guint64 mword;
#endif
+typedef mword SgenDescriptor;
+#define SGEN_DESCRIPTOR_NULL 0
/*
* Turning on heavy statistics will turn off the managed allocator and
static int complex_descriptors_next = 0;
static SgenUserRootMarkFunc user_descriptors [MAX_USER_DESCRIPTORS];
static int user_descriptors_next = 0;
-static void *all_ref_root_descrs [32];
+static SgenDescriptor all_ref_root_descrs [32];
#ifdef HEAVY_STATISTICS
static guint64 stat_scanned_count_per_descriptor [DESC_TYPE_MAX];
/*
* Descriptor builders.
*/
-void*
+SgenDescriptor
mono_gc_make_descr_for_object (gsize *bitmap, int numbits, size_t obj_size)
{
int first_set = -1, num_set = 0, last_set = -1, i;
if (first_set < 0) {
SGEN_LOG (6, "Ptrfree descriptor %p, size: %zd", (void*)desc, stored_size);
if (stored_size <= MAX_RUNLEN_OBJECT_SIZE && stored_size <= SGEN_MAX_SMALL_OBJ_SIZE)
- return (void*)(DESC_TYPE_SMALL_PTRFREE | stored_size);
- return (void*)DESC_TYPE_COMPLEX_PTRFREE;
+ return DESC_TYPE_SMALL_PTRFREE | stored_size;
+ return DESC_TYPE_COMPLEX_PTRFREE;
}
g_assert (!(stored_size & 0x7));
if (last_set < BITMAP_NUM_BITS + OBJECT_HEADER_WORDS && stored_size <= SGEN_MAX_SMALL_OBJ_SIZE) {
desc = DESC_TYPE_BITMAP | ((*bitmap >> OBJECT_HEADER_WORDS) << LOW_TYPE_BITS);
SGEN_LOG (6, "Largebitmap descriptor %p, size: %zd, last set: %d", (void*)desc, stored_size, last_set);
- return (void*) desc;
+ return desc;
}
if (stored_size <= MAX_RUNLEN_OBJECT_SIZE && stored_size <= SGEN_MAX_SMALL_OBJ_SIZE) {
if (first_set < 256 && num_set < 256 && (first_set + num_set == last_set + 1)) {
desc = DESC_TYPE_RUN_LENGTH | stored_size | (first_set << 16) | (num_set << 24);
SGEN_LOG (6, "Runlen descriptor %p, size: %zd, first set: %d, num set: %d", (void*)desc, stored_size, first_set, num_set);
- return (void*) desc;
+ return desc;
}
}
/* it's a complex object ... */
desc = DESC_TYPE_COMPLEX | (alloc_complex_descriptor (bitmap, last_set + 1) << LOW_TYPE_BITS);
- return (void*) desc;
+ return desc;
}
/* If the array holds references, numbits == 1 and the first bit is set in elem_bitmap */
-void*
+SgenDescriptor
mono_gc_make_descr_for_array (int vector, gsize *elem_bitmap, int numbits, size_t elem_size)
{
int first_set = -1, num_set = 0, last_set = -1, i;
if (first_set < 0) {
if (elem_size <= MAX_ELEMENT_SIZE)
- return (void*)(desc | VECTOR_SUBTYPE_PTRFREE | (elem_size << VECTOR_ELSIZE_SHIFT));
- return (void*)DESC_TYPE_COMPLEX_PTRFREE;
+ return desc | VECTOR_SUBTYPE_PTRFREE | (elem_size << VECTOR_ELSIZE_SHIFT);
+ return DESC_TYPE_COMPLEX_PTRFREE;
}
if (elem_size <= MAX_ELEMENT_SIZE) {
desc |= elem_size << VECTOR_ELSIZE_SHIFT;
if (!num_set) {
- return (void*)(desc | VECTOR_SUBTYPE_PTRFREE);
+ return desc | VECTOR_SUBTYPE_PTRFREE;
}
/* Note: we also handle structs with just ref fields */
if (num_set * sizeof (gpointer) == elem_size) {
- return (void*)(desc | VECTOR_SUBTYPE_REFS | ((gssize)(-1) << 16));
+ return desc | VECTOR_SUBTYPE_REFS | ((gssize)(-1) << 16);
}
/* FIXME: try run-len first */
/* Note: we can't skip the object header here, because it's not present */
if (last_set < VECTOR_BITMAP_SIZE) {
- return (void*)(desc | VECTOR_SUBTYPE_BITMAP | (*elem_bitmap << 16));
+ return desc | VECTOR_SUBTYPE_BITMAP | (*elem_bitmap << 16);
}
}
/* it's am array of complex structs ... */
desc = DESC_TYPE_COMPLEX_ARR;
desc |= alloc_complex_descriptor (elem_bitmap, last_set + 1) << LOW_TYPE_BITS;
- return (void*) desc;
+ return desc;
}
/* Return the bitmap encoded by a descriptor */
gsize*
-mono_gc_get_bitmap_for_descr (void *descr, int *numbits)
+mono_gc_get_bitmap_for_descr (SgenDescriptor descr, int *numbits)
{
SgenDescriptor d = (SgenDescriptor)descr;
gsize *bitmap;
}
}
-void*
+SgenDescriptor
mono_gc_make_descr_from_bitmap (gsize *bitmap, int numbits)
{
if (numbits == 0) {
- return (void*)MAKE_ROOT_DESC (ROOT_DESC_BITMAP, 0);
+ return MAKE_ROOT_DESC (ROOT_DESC_BITMAP, 0);
} else if (numbits < ((sizeof (*bitmap) * 8) - ROOT_DESC_TYPE_SHIFT)) {
- return (void*)MAKE_ROOT_DESC (ROOT_DESC_BITMAP, bitmap [0]);
+ return MAKE_ROOT_DESC (ROOT_DESC_BITMAP, bitmap [0]);
} else {
SgenDescriptor complex = alloc_complex_descriptor (bitmap, numbits);
- return (void*)MAKE_ROOT_DESC (ROOT_DESC_COMPLEX, complex);
+ return MAKE_ROOT_DESC (ROOT_DESC_COMPLEX, complex);
}
}
-void*
+SgenDescriptor
mono_gc_make_root_descr_all_refs (int numbits)
{
gsize *gc_bitmap;
- void *descr;
+ SgenDescriptor descr;
int num_bytes = numbits / 8;
if (numbits < 32 && all_ref_root_descrs [numbits])
SGEN_GC_BIT_FINALIZER_AWARE = 4,
};
-typedef mword SgenDescriptor;
-
void sgen_gc_init (void);
void sgen_os_init (void);