#ifdef SGEN_DEFINE_OBJECT_VTABLE
-#include "metadata/sgen-archdep.h"
+#include "sgen/sgen-archdep.h"
#include "utils/mono-threads.h"
#include "utils/mono-mmap.h"
+#include "metadata/object-internals.h"
typedef MonoObject GCObject;
-typedef MonoVTable GCVTable;
+typedef MonoVTable* GCVTable;
-/* FIXME: This should return a GCVTable* and be a function. */
-#define SGEN_LOAD_VTABLE_UNCHECKED(obj) ((void*)(((GCObject*)(obj))->vtable))
-
-static inline mword
-sgen_vtable_get_descriptor (GCVTable *vtable)
+static inline GCVTable
+SGEN_LOAD_VTABLE_UNCHECKED (GCObject *obj)
{
- return (mword)vtable->gc_descr;
+ return obj->vtable;
}
-static mword /*__attribute__((noinline)) not sure if this hint is a good idea*/
-sgen_client_slow_object_get_size (GCVTable *vtable, GCObject* o)
+static inline SgenDescriptor
+sgen_vtable_get_descriptor (GCVTable vtable)
{
- MonoClass *klass = ((MonoVTable*)vtable)->klass;
-
- /*
- * We depend on mono_string_length_fast and
- * mono_array_length_fast not using the object's vtable.
- */
- if (klass == mono_defaults.string_class) {
- return G_STRUCT_OFFSET (MonoString, chars) + 2 * mono_string_length_fast ((MonoString*) o) + 2;
- } else if (klass->rank) {
- MonoArray *array = (MonoArray*)o;
- size_t size = sizeof (MonoArray) + klass->sizes.element_size * mono_array_length_fast (array);
- if (G_UNLIKELY (array->bounds)) {
- size += sizeof (mono_array_size_t) - 1;
- size &= ~(sizeof (mono_array_size_t) - 1);
- size += sizeof (MonoArrayBounds) * klass->rank;
- }
- return size;
- } else {
- /* from a created object: the class must be inited already */
- return klass->instance_size;
- }
-}
-
-/*
- * This function can be called on an object whose first word, the
- * vtable field, is not intact. This is necessary for the parallel
- * collector.
- */
-static MONO_NEVER_INLINE mword
-sgen_client_par_object_get_size (GCVTable *vtable, GCObject* o)
-{
- mword descr = sgen_vtable_get_descriptor (vtable);
- mword type = descr & DESC_TYPE_MASK;
-
- if (type == DESC_TYPE_RUN_LENGTH || type == DESC_TYPE_SMALL_PTRFREE) {
- mword size = descr & 0xfff8;
- SGEN_ASSERT (9, size >= sizeof (MonoObject), "Run length object size to small");
- return size;
- } else if (descr == SGEN_DESC_STRING) {
- return G_STRUCT_OFFSET (MonoString, chars) + 2 * mono_string_length_fast ((MonoString*) o) + 2;
- } else if (type == DESC_TYPE_VECTOR) {
- int element_size = ((descr) >> VECTOR_ELSIZE_SHIFT) & MAX_ELEMENT_SIZE;
- MonoArray *array = (MonoArray*)o;
- size_t size = sizeof (MonoArray) + element_size * mono_array_length_fast (array);
-
- /*
- * Non-vector arrays with a single dimension whose lower bound is zero are
- * allocated without bounds.
- */
- if ((descr & VECTOR_KIND_ARRAY) && array->bounds) {
- size += sizeof (mono_array_size_t) - 1;
- size &= ~(sizeof (mono_array_size_t) - 1);
- size += sizeof (MonoArrayBounds) * ((MonoVTable*)vtable)->klass->rank;
- }
- return size;
- }
-
- return sgen_client_slow_object_get_size (vtable, o);
+ return (SgenDescriptor)vtable->gc_descr;
}
typedef struct _SgenClientThreadInfo SgenClientThreadInfo;
*/
gboolean gc_disabled;
+#ifdef SGEN_POSIX_STW
+ /* This is -1 until the first suspend. */
+ int signal;
+ /* FIXME: kill this, we only use signals on systems that have rt-posix, which doesn't have issues with duplicates. */
+ unsigned int stop_count; /* to catch duplicate signals. */
+#endif
+
gpointer runtime_data;
void *stack_end;
#include "utils/mono-counters.h"
#include "utils/mono-logger-internal.h"
#include "utils/mono-time.h"
+#include "utils/mono-semaphore.h"
+#include "metadata/sgen-bridge-internal.h"
extern void mono_sgen_register_moved_object (void *obj, void *destination);
extern void mono_sgen_gc_event_moves (void);
INTERNAL_MEM_MAX
};
+static inline mword
+sgen_mono_array_size (GCVTable vtable, MonoArray *array, mword *bounds_size, mword descr)
+{
+ mword size, size_without_bounds;
+ int element_size;
+
+ if ((descr & DESC_TYPE_MASK) == DESC_TYPE_VECTOR)
+ element_size = ((descr) >> VECTOR_ELSIZE_SHIFT) & MAX_ELEMENT_SIZE;
+ else
+ element_size = vtable->klass->sizes.element_size;
+
+ size_without_bounds = size = sizeof (MonoArray) + element_size * mono_array_length_fast (array);
+
+ if (G_UNLIKELY (array->bounds)) {
+ size += sizeof (mono_array_size_t) - 1;
+ size &= ~(sizeof (mono_array_size_t) - 1);
+ size += sizeof (MonoArrayBounds) * vtable->klass->rank;
+ }
+
+ if (bounds_size)
+ *bounds_size = size - size_without_bounds;
+ return size;
+}
+
#define SGEN_CLIENT_OBJECT_HEADER_SIZE (sizeof (GCObject))
#define SGEN_CLIENT_MINIMUM_OBJECT_SIZE SGEN_CLIENT_OBJECT_HEADER_SIZE
+static mword /*__attribute__((noinline)) not sure if this hint is a good idea*/
+sgen_client_slow_object_get_size (GCVTable vtable, GCObject* o)
+{
+ MonoClass *klass = ((MonoVTable*)vtable)->klass;
+
+ /*
+ * We depend on mono_string_length_fast and
+ * mono_array_length_fast not using the object's vtable.
+ */
+ if (klass == mono_defaults.string_class) {
+ return G_STRUCT_OFFSET (MonoString, chars) + 2 * mono_string_length_fast ((MonoString*) o) + 2;
+ } else if (klass->rank) {
+ return sgen_mono_array_size (vtable, (MonoArray*)o, NULL, 0);
+ } else {
+ /* from a created object: the class must be inited already */
+ return klass->instance_size;
+ }
+}
+
+/*
+ * This function can be called on an object whose first word, the
+ * vtable field, is not intact. This is necessary for the parallel
+ * collector.
+ */
+static MONO_NEVER_INLINE mword
+sgen_client_par_object_get_size (GCVTable vtable, GCObject* o)
+{
+ SgenDescriptor descr = sgen_vtable_get_descriptor (vtable);
+ mword type = descr & DESC_TYPE_MASK;
+
+ if (type == DESC_TYPE_RUN_LENGTH || type == DESC_TYPE_SMALL_PTRFREE) {
+ mword size = descr & 0xfff8;
+ SGEN_ASSERT (9, size >= sizeof (MonoObject), "Run length object size to small");
+ return size;
+ } else if (descr == SGEN_DESC_STRING) {
+ return G_STRUCT_OFFSET (MonoString, chars) + 2 * mono_string_length_fast ((MonoString*) o) + 2;
+ } else if (type == DESC_TYPE_VECTOR) {
+ return sgen_mono_array_size (vtable, (MonoArray*)o, NULL, descr);
+ }
+
+ return sgen_client_slow_object_get_size (vtable, o);
+}
+
static MONO_ALWAYS_INLINE size_t G_GNUC_UNUSED
-sgen_client_array_element_size (GCVTable *gc_vtable)
+sgen_client_array_element_size (GCVTable gc_vtable)
{
MonoVTable *vt = (MonoVTable*)gc_vtable;
return mono_array_element_size (vt->klass);
return ((MonoObject*)o)->synchronisation == GINT_TO_POINTER (-1);
}
-/* FIXME: Why do we even need this? Can't we get it from the descriptor? */
-static gboolean G_GNUC_UNUSED
-sgen_client_vtable_has_references (GCVTable *vt)
-{
- return ((MonoVTable*)vt)->klass->has_references;
-}
-
static MONO_ALWAYS_INLINE void G_GNUC_UNUSED
-sgen_client_pre_copy_checks (char *destination, GCVTable *gc_vtable, void *obj, mword objsize)
+sgen_client_pre_copy_checks (char *destination, GCVTable gc_vtable, void *obj, mword objsize)
{
MonoVTable *vt = (MonoVTable*)gc_vtable;
SGEN_ASSERT (9, vt->klass->inited, "vtable %p for class %s:%s was not initialized", vt, vt->klass->name_space, vt->klass->name);
}
static MONO_ALWAYS_INLINE void G_GNUC_UNUSED
-sgen_client_update_copied_object (char *destination, GCVTable *gc_vtable, void *obj, mword objsize)
+sgen_client_update_copied_object (char *destination, GCVTable gc_vtable, void *obj, mword objsize)
{
MonoVTable *vt = (MonoVTable*)gc_vtable;
if (G_UNLIKELY (vt->rank && ((MonoArray*)obj)->bounds)) {
if (!mono_defaults.critical_finalizer_object)
return FALSE;
- class = ((MonoVTable*)SGEN_LOAD_VTABLE (obj))->klass;
+ class = SGEN_LOAD_VTABLE (obj)->klass;
return mono_class_has_parent_fast (class, mono_defaults.critical_finalizer_object);
}
-const char* sgen_client_vtable_get_namespace (GCVTable *vtable);
-const char* sgen_client_vtable_get_name (GCVTable *vtable);
+const char* sgen_client_vtable_get_namespace (GCVTable vtable);
+const char* sgen_client_vtable_get_name (GCVTable vtable);
+
+static gboolean G_GNUC_UNUSED
+sgen_client_bridge_need_processing (void)
+{
+ return sgen_need_bridge_processing ();
+}
+
+static void G_GNUC_UNUSED
+sgen_client_bridge_reset_data (void)
+{
+ sgen_bridge_reset_data ();
+}
+
+static void G_GNUC_UNUSED
+sgen_client_bridge_processing_stw_step (void)
+{
+ sgen_bridge_processing_stw_step ();
+}
+
+static void G_GNUC_UNUSED
+sgen_client_bridge_wait_for_processing (void)
+{
+ mono_gc_wait_for_bridge_processing ();
+}
+
+static void G_GNUC_UNUSED
+sgen_client_bridge_processing_finish (int generation)
+{
+ sgen_bridge_processing_finish (generation);
+}
+
+static gboolean G_GNUC_UNUSED
+sgen_client_bridge_is_bridge_object (GCObject *obj)
+{
+ return sgen_is_bridge_object (obj);
+}
+
+static void G_GNUC_UNUSED
+sgen_client_bridge_register_finalized_object (GCObject *object)
+{
+ sgen_bridge_register_finalized_object (object);
+}
static void G_GNUC_UNUSED
sgen_client_binary_protocol_collection_requested (int generation, size_t requested_size, gboolean force)
MONO_GC_BEGIN (generation);
mono_profiler_gc_event (MONO_GC_EVENT_START, generation);
+
+#ifndef DISABLE_PERFCOUNTERS
+ if (generation == GENERATION_NURSERY)
+ mono_perfcounters->gc_collections0++;
+ else
+ mono_perfcounters->gc_collections1++;
+#endif
}
static void G_GNUC_UNUSED
}
static void G_GNUC_UNUSED
-sgen_client_binary_protocol_world_stopping (int generation, long long timestamp)
+sgen_client_binary_protocol_world_stopping (int generation, long long timestamp, gpointer thread)
{
MONO_GC_WORLD_STOP_BEGIN ();
mono_profiler_gc_event (MONO_GC_EVENT_POST_START_WORLD, generation);
}
+static void G_GNUC_UNUSED
+sgen_client_binary_protocol_block_alloc (gpointer addr, size_t size)
+{
+}
+
+static void G_GNUC_UNUSED
+sgen_client_binary_protocol_block_free (gpointer addr, size_t size)
+{
+}
+
+static void G_GNUC_UNUSED
+sgen_client_binary_protocol_block_set_state (gpointer addr, size_t size, int old, int new)
+{
+}
+
static void G_GNUC_UNUSED
sgen_client_binary_protocol_mark_start (int generation)
{
}
static void G_GNUC_UNUSED
-sgen_client_binary_protocol_alloc (gpointer obj, gpointer vtable, size_t size)
+sgen_client_binary_protocol_alloc (gpointer obj, gpointer vtable, size_t size, gpointer provenance)
{
mono_binary_protocol_alloc_generic (obj, vtable, size, FALSE);
}
static void G_GNUC_UNUSED
-sgen_client_binary_protocol_alloc_pinned (gpointer obj, gpointer vtable, size_t size)
+sgen_client_binary_protocol_alloc_pinned (gpointer obj, gpointer vtable, size_t size, gpointer provenance)
{
mono_binary_protocol_alloc_generic (obj, vtable, size, TRUE);
}
static void G_GNUC_UNUSED
-sgen_client_binary_protocol_alloc_degraded (gpointer obj, gpointer vtable, size_t size)
+sgen_client_binary_protocol_alloc_degraded (gpointer obj, gpointer vtable, size_t size, gpointer provenance)
{
MONO_GC_MAJOR_OBJ_ALLOC_DEGRADED ((mword)obj, size, sgen_client_vtable_get_namespace (vtable), sgen_client_vtable_get_name (vtable));
}
+static void G_GNUC_UNUSED
+sgen_client_binary_protocol_card_scan (gpointer start, size_t size)
+{
+}
+
+static void G_GNUC_UNUSED
+sgen_client_binary_protocol_pin_stage (gpointer addr_ptr, gpointer addr)
+{
+}
+
+static void G_GNUC_UNUSED
+sgen_client_binary_protocol_cement_stage (gpointer addr)
+{
+}
+
static void G_GNUC_UNUSED
sgen_client_binary_protocol_pin (gpointer obj, gpointer vtable, size_t size)
{
#endif
}
+static void G_GNUC_UNUSED
+sgen_client_binary_protocol_mark (gpointer obj, gpointer vtable, size_t size)
+{
+}
+
+static void G_GNUC_UNUSED
+sgen_client_binary_protocol_scan_begin (gpointer obj, gpointer vtable, size_t size)
+{
+}
+
+static void G_GNUC_UNUSED
+sgen_client_binary_protocol_scan_vtype_begin (gpointer obj, size_t size)
+{
+}
+
+static void G_GNUC_UNUSED
+sgen_client_binary_protocol_scan_process_reference (gpointer obj, gpointer ptr, gpointer value)
+{
+}
+
+static void G_GNUC_UNUSED
+sgen_client_binary_protocol_scan_stack (gpointer thread, gpointer stack_start, gpointer stack_end, int skip_reason)
+{
+}
+
+static void G_GNUC_UNUSED
+sgen_client_binary_protocol_wbarrier (gpointer ptr, gpointer value, gpointer value_vtable)
+{
+}
+
static void G_GNUC_UNUSED
sgen_client_binary_protocol_cement (gpointer ptr, gpointer vtable, size_t size)
{
}
static void G_GNUC_UNUSED
-sgen_client_binary_protocol_dislink_update (gpointer link, gpointer obj, gboolean track, gboolean staged)
+sgen_client_binary_protocol_ptr_update (gpointer ptr, gpointer old_value, gpointer new_value, gpointer vtable, size_t size)
+{
+}
+
+static void G_GNUC_UNUSED
+sgen_client_binary_protocol_cleanup (gpointer ptr, gpointer vtable, size_t size)
+{
+}
+
+static void G_GNUC_UNUSED
+sgen_client_binary_protocol_dislink_add (gpointer link, gpointer obj, gboolean track)
+{
+}
+
+static void G_GNUC_UNUSED
+sgen_client_binary_protocol_dislink_update (gpointer link, gpointer obj, gboolean track)
{
#ifdef ENABLE_DTRACE
if (MONO_GC_WEAK_UPDATE_ENABLED ()) {
- GCVTable *vt = obj ? (GCVTable*)SGEN_LOAD_VTABLE (obj) : NULL;
+ GCVTable vt = obj ? SGEN_LOAD_VTABLE (obj) : NULL;
MONO_GC_WEAK_UPDATE ((mword)link,
(mword)obj,
obj ? (mword)sgen_safe_object_get_size (obj) : (mword)0,
#endif
}
+static void G_GNUC_UNUSED
+sgen_client_binary_protocol_dislink_remove (gpointer link, gboolean track)
+{
+}
+
static void G_GNUC_UNUSED
sgen_client_binary_protocol_empty (gpointer start, size_t size)
{
{
}
+static void G_GNUC_UNUSED
+sgen_client_binary_protocol_gray_enqueue (gpointer queue, gpointer cursor, gpointer value)
+{
+}
+
+static void G_GNUC_UNUSED
+sgen_client_binary_protocol_gray_dequeue (gpointer queue, gpointer cursor, gpointer value)
+{
+}
+
int sgen_thread_handshake (BOOL suspend);
gboolean sgen_suspend_thread (SgenThreadInfo *info);
gboolean sgen_resume_thread (SgenThreadInfo *info);
void sgen_wait_for_suspend_ack (int count);
#ifdef HAVE_KW_THREAD
+extern __thread SgenThreadInfo *sgen_thread_info;
#define TLAB_ACCESS_INIT
#define IN_CRITICAL_REGION sgen_thread_info->client_info.in_critical_region
#else
+extern MonoNativeTlsKey thread_info_key;
#define TLAB_ACCESS_INIT SgenThreadInfo *__thread_info__ = mono_native_tls_get_value (thread_info_key)
#define IN_CRITICAL_REGION (__thread_info__->client_info.in_critical_region)
#endif
#define SGEN_TV_DECLARE(name) gint64 name
#define SGEN_TV_GETTIME(tv) tv = mono_100ns_ticks ()
-#define SGEN_TV_ELAPSED(start,end) (int)((end-start))
+#define SGEN_TV_ELAPSED(start,end) ((long)(end-start))
+
+typedef MonoSemType SgenSemaphore;
+
+#define SGEN_SEMAPHORE_INIT(sem,initial) MONO_SEM_INIT ((sem), (initial))
+#define SGEN_SEMAPHORE_POST(sem) MONO_SEM_POST ((sem))
+#define SGEN_SEMAPHORE_WAIT(sem) MONO_SEM_WAIT ((sem))
+
+gboolean sgen_has_critical_method (void);
+gboolean sgen_is_critical_method (MonoMethod *method);
+
+void sgen_set_use_managed_allocator (gboolean flag);
+gboolean sgen_is_managed_allocator (MonoMethod *method);
+gboolean sgen_has_managed_allocator (void);
+
+void sgen_scan_for_registered_roots_in_domain (MonoDomain *domain, int root_type);
+void sgen_null_links_for_domain (MonoDomain *domain);
#endif