Merge pull request #2183 from joelmartinez/monodoc-ecmacref-fix
[mono.git] / mono / metadata / sgen-client-mono.h
index eb52ac990f34625a2e2b49552776b62c65363de9..ab0cedf6ad6d6fa1a27749b87a43bd9788bb3da2 100644 (file)
 #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;
@@ -148,10 +88,10 @@ struct _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);
@@ -163,11 +103,78 @@ enum {
        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);
@@ -192,14 +199,14 @@ sgen_client_object_is_array_fill (GCObject *o)
 }
 
 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)) {
@@ -237,18 +244,18 @@ extern gboolean sgen_mono_xdomain_checks;
 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)
@@ -564,11 +571,16 @@ sgen_client_binary_protocol_cleanup (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_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,
@@ -580,12 +592,7 @@ sgen_client_binary_protocol_dislink_update (gpointer link, gpointer obj, gboolea
 }
 
 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)
 {
 }
 
@@ -699,5 +706,6 @@ 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