#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;
#include "metadata/profiler-private.h"
#include "utils/dtrace.h"
#include "utils/mono-counters.h"
-#include "utils/mono-logger-internal.h"
+#include "utils/mono-logger-internals.h"
#include "utils/mono-time.h"
#include "utils/mono-semaphore.h"
-#include "metadata/sgen-bridge-internal.h"
+#include "metadata/sgen-bridge-internals.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);
}
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)) {
static gboolean G_GNUC_UNUSED
sgen_client_object_has_critical_finalizer (GCObject *obj)
{
- MonoClass *class;
+ MonoClass *klass;
if (!mono_defaults.critical_finalizer_object)
return FALSE;
- class = ((MonoVTable*)SGEN_LOAD_VTABLE (obj))->klass;
+ klass = SGEN_LOAD_VTABLE (obj)->klass;
- return mono_class_has_parent_fast (class, mono_defaults.critical_finalizer_object);
+ return mono_class_has_parent_fast (klass, 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)
}
static void G_GNUC_UNUSED
-sgen_client_binary_protocol_dislink_update (gpointer link, gpointer obj, gboolean track, gboolean staged)
+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,
}
static void G_GNUC_UNUSED
-sgen_client_binary_protocol_dislink_update_staged (gpointer link, gpointer obj, gboolean track, int index)
-{
-}
-
-static void G_GNUC_UNUSED
-sgen_client_binary_protocol_dislink_process_staged (gpointer link, gpointer obj, int index)
+sgen_client_binary_protocol_dislink_remove (gpointer link, gboolean track)
{
}
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