Merge pull request #900 from Blewzman/FixAggregateExceptionGetBaseException
[mono.git] / mono / metadata / sgen-gc.h
index 6fd92c03b3a73e1e892bf5af8fcf4048fe54da71..126f561ca7eca0a5fa42907f5f6dc7e977bec28a 100644 (file)
@@ -39,7 +39,8 @@ typedef struct _SgenThreadInfo SgenThreadInfo;
 #include <mono/utils/mono-threads.h>
 #include <mono/utils/dtrace.h>
 #include <mono/utils/mono-logger-internal.h>
-#include <mono/io-layer/mono-mutex.h>
+#include <mono/utils/atomic.h>
+#include <mono/utils/mono-mutex.h>
 #include <mono/metadata/class-internals.h>
 #include <mono/metadata/object-internals.h>
 #include <mono/metadata/sgen-conf.h>
@@ -65,17 +66,30 @@ NurseryClearPolicy sgen_get_nursery_clear_policy (void) MONO_INTERNAL;
 #define SGEN_TV_ELAPSED(start,end) (int)((end-start) / 10)
 #define SGEN_TV_ELAPSED_MS(start,end) ((SGEN_TV_ELAPSED((start),(end)) + 500) / 1000)
 
+#if !defined(__MACH__) && !MONO_MACH_ARCH_SUPPORTED && defined(HAVE_PTHREAD_KILL)
+#define SGEN_POSIX_STW 1
+#endif
+
 /* eventually share with MonoThread? */
 /*
  * This structure extends the MonoThreadInfo structure.
  */
 struct _SgenThreadInfo {
        MonoThreadInfo info;
+       /*
+       This is set to TRUE when STW fails to suspend a thread, most probably because the
+       underlying thread is dead.
+       */
        int skip;
        volatile int in_critical_region;
-       gboolean joined_stw;
-       gboolean doing_handshake;
-       gboolean thread_is_dying;
+
+       /*
+       This is set the argument of mono_gc_set_skip_thread.
+
+       A thread that knowingly holds no managed state can call this
+       function around blocking loops to reduce the GC burden by not
+       been scanned.
+       */
        gboolean gc_disabled;
        void *stack_end;
        void *stack_start;
@@ -86,14 +100,17 @@ struct _SgenThreadInfo {
        char **tlab_real_end_addr;
        gpointer runtime_data;
 
-       /* Only used on POSIX platforms */
+#ifdef SGEN_POSIX_STW
+       /* This is -1 until the first suspend. */
        int signal;
-       /* Ditto */
-       unsigned int stop_count; /* to catch duplicate signals */
+       /* 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 stopped_ip;    /* only valid if the thread is stopped */
-       MonoDomain *stopped_domain; /* ditto */
+       MonoDomain *stopped_domain; /* dsto */
 
+       /*FIXME pretty please finish killing ARCH_NUM_REGS */
 #ifdef USE_MONO_CTX
        MonoContext ctx;                /* ditto */
 #else
@@ -126,7 +143,7 @@ struct _GCMemSection {
        /* in major collections indexes in the pin_queue for objects that pin this section */
        void **pin_queue_start;
        int pin_queue_num_entries;
-       unsigned short num_scan_start;
+       unsigned int num_scan_start;
 };
 
 /*
@@ -135,16 +152,13 @@ struct _GCMemSection {
 #define LOCK_DECLARE(name) mono_mutex_t name
 /* if changing LOCK_INIT to something that isn't idempotent, look at
    its use in mono_gc_base_init in sgen-gc.c */
-#define LOCK_INIT(name)        mono_mutex_init (&(name), NULL)
+#define LOCK_INIT(name)        mono_mutex_init (&(name))
 #define LOCK_GC do {                                           \
                mono_mutex_lock (&gc_mutex);                    \
                MONO_GC_LOCKED ();                              \
        } while (0)
 #define TRYLOCK_GC (mono_mutex_trylock (&gc_mutex) == 0)
-#define UNLOCK_GC do {                                         \
-               mono_mutex_unlock (&gc_mutex);                  \
-               MONO_GC_UNLOCKED ();                            \
-       } while (0)
+#define UNLOCK_GC do { sgen_gc_unlock (); } while (0)
 
 extern LOCK_DECLARE (sgen_interruption_mutex);
 
@@ -219,6 +233,8 @@ extern int num_ready_finalizers;
 #define SGEN_ALLOC_ALIGN               8
 #define SGEN_ALLOC_ALIGN_BITS  3
 
+/* s must be non-negative */
+#define SGEN_CAN_ALIGN_UP(s)           ((s) <= SIZE_MAX - (SGEN_ALLOC_ALIGN - 1))
 #define SGEN_ALIGN_UP(s)               (((s)+(SGEN_ALLOC_ALIGN-1)) & ~(SGEN_ALLOC_ALIGN-1))
 
 /*
@@ -262,19 +278,19 @@ extern int sgen_nursery_bits MONO_INTERNAL;
 extern char *sgen_nursery_start MONO_INTERNAL;
 extern char *sgen_nursery_end MONO_INTERNAL;
 
-static inline gboolean
+static inline MONO_ALWAYS_INLINE gboolean
 sgen_ptr_in_nursery (void *p)
 {
        return SGEN_PTR_IN_NURSERY ((p), DEFAULT_NURSERY_BITS, sgen_nursery_start, sgen_nursery_end);
 }
 
-static inline char*
+static inline MONO_ALWAYS_INLINE char*
 sgen_get_nursery_start (void)
 {
        return sgen_nursery_start;
 }
 
-static inline char*
+static inline MONO_ALWAYS_INLINE char*
 sgen_get_nursery_end (void)
 {
        return sgen_nursery_end;
@@ -375,7 +391,6 @@ int sgen_thread_handshake (BOOL suspend) MONO_INTERNAL;
 gboolean sgen_suspend_thread (SgenThreadInfo *info) MONO_INTERNAL;
 gboolean sgen_resume_thread (SgenThreadInfo *info) MONO_INTERNAL;
 void sgen_wait_for_suspend_ack (int count) MONO_INTERNAL;
-gboolean sgen_park_current_thread_if_doing_handshake (SgenThreadInfo *p) MONO_INTERNAL;
 void sgen_os_init (void) MONO_INTERNAL;
 
 gboolean sgen_is_worker_thread (MonoNativeThreadId thread) MONO_INTERNAL;
@@ -404,6 +419,7 @@ enum {
        INTERNAL_MEM_GRAY_QUEUE,
        INTERNAL_MEM_MS_TABLES,
        INTERNAL_MEM_MS_BLOCK_INFO,
+       INTERNAL_MEM_MS_BLOCK_INFO_SORT,
        INTERNAL_MEM_EPHEMERON_LINK,
        INTERNAL_MEM_WORKER_DATA,
        INTERNAL_MEM_WORKER_JOB_DATA,
@@ -415,6 +431,7 @@ enum {
        INTERNAL_MEM_JOB_QUEUE_ENTRY,
        INTERNAL_MEM_TOGGLEREF_DATA,
        INTERNAL_MEM_CARDTABLE_MOD_UNION,
+       INTERNAL_MEM_BINARY_PROTOCOL,
        INTERNAL_MEM_MAX
 };
 
@@ -464,8 +481,6 @@ void sgen_free_internal (void *addr, int type) MONO_INTERNAL;
 void* sgen_alloc_internal_dynamic (size_t size, int type, gboolean assert_on_failure) MONO_INTERNAL;
 void sgen_free_internal_dynamic (void *addr, size_t size, int type) MONO_INTERNAL;
 
-gboolean sgen_parse_environment_string_extract_number (const char *str, glong *out) MONO_INTERNAL;
-
 void** sgen_find_optimized_pin_queue_area (void *start, void *end, int *num) MONO_INTERNAL;
 void sgen_find_section_pin_queue_start_end (GCMemSection *section) MONO_INTERNAL;
 void sgen_pin_objects_in_section (GCMemSection *section, ScanCopyContext ctx) MONO_INTERNAL;
@@ -660,7 +675,8 @@ struct _SgenMajorCollector {
        void (*init_worker_thread) (void *data);
        void (*reset_worker_data) (void *data);
        gboolean (*is_valid_object) (char *object);
-       gboolean (*describe_pointer) (char *pointer);
+       MonoVTable* (*describe_pointer) (char *pointer);
+       guint8* (*get_cardtable_mod_union_for_object) (char *object);
        long long (*get_and_reset_num_major_objects_marked) (void);
 };
 
@@ -689,6 +705,7 @@ typedef struct {
 
        void (*finish_minor_collection) (void);
        gboolean (*find_address) (char *addr);
+       gboolean (*find_address_with_cards) (char *cards_start, guint8 *cards, char *addr);
 } SgenRemeberedSet;
 
 SgenRemeberedSet *sgen_get_remset (void) MONO_INTERNAL;
@@ -766,6 +783,8 @@ const char* sgen_safe_name (void* obj) MONO_INTERNAL;
 
 gboolean sgen_object_is_live (void *obj) MONO_INTERNAL;
 
+void  sgen_init_fin_weak_hash (void) MONO_INTERNAL;
+
 gboolean sgen_need_bridge_processing (void) MONO_INTERNAL;
 void sgen_bridge_reset_data (void) MONO_INTERNAL;
 void sgen_bridge_processing_stw_step (void) MONO_INTERNAL;
@@ -775,6 +794,7 @@ gboolean sgen_is_bridge_object (MonoObject *obj) MONO_INTERNAL;
 gboolean sgen_is_bridge_class (MonoClass *class) MONO_INTERNAL;
 void sgen_mark_bridge_object (MonoObject *obj) MONO_INTERNAL;
 void sgen_bridge_register_finalized_object (MonoObject *object) MONO_INTERNAL;
+void sgen_bridge_describe_pointer (MonoObject *object) MONO_INTERNAL;
 
 void sgen_scan_togglerefs (char *start, char *end, ScanCopyContext ctx) MONO_INTERNAL;
 void sgen_process_togglerefs (void) MONO_INTERNAL;
@@ -925,28 +945,24 @@ extern __thread char *stack_end;
 #endif
 
 #ifdef HAVE_KW_THREAD
-#define EMIT_TLS_ACCESS(mb,dummy,offset)       do {    \
+#define EMIT_TLS_ACCESS(mb,member,key) do {    \
        mono_mb_emit_byte ((mb), MONO_CUSTOM_PREFIX);   \
        mono_mb_emit_byte ((mb), CEE_MONO_TLS);         \
-       mono_mb_emit_i4 ((mb), (offset));               \
+       mono_mb_emit_i4 ((mb), (key));          \
        } while (0)
 #else
 
-/* 
- * CEE_MONO_TLS requires the tls offset, not the key, so the code below only works on darwin,
- * where the two are the same.
- */
 #if defined(__APPLE__) || defined (HOST_WIN32)
-#define EMIT_TLS_ACCESS(mb,member,dummy)       do {    \
+#define EMIT_TLS_ACCESS(mb,member,key) do {    \
        mono_mb_emit_byte ((mb), MONO_CUSTOM_PREFIX);   \
        mono_mb_emit_byte ((mb), CEE_MONO_TLS);         \
-       mono_mb_emit_i4 ((mb), thread_info_key);        \
+       mono_mb_emit_i4 ((mb), TLS_KEY_SGEN_THREAD_INFO);       \
        mono_mb_emit_icon ((mb), G_STRUCT_OFFSET (SgenThreadInfo, member));     \
        mono_mb_emit_byte ((mb), CEE_ADD);              \
        mono_mb_emit_byte ((mb), CEE_LDIND_I);          \
        } while (0)
 #else
-#define EMIT_TLS_ACCESS(mb,member,dummy)       do { g_error ("sgen is not supported when using --with-tls=pthread.\n"); } while (0)
+#define EMIT_TLS_ACCESS(mb,member,key) do { g_error ("sgen is not supported when using --with-tls=pthread.\n"); } while (0)
 #endif
 
 #endif
@@ -962,6 +978,7 @@ extern int degraded_mode;
 extern int default_nursery_size;
 extern guint32 tlab_size;
 extern NurseryClearPolicy nursery_clear_policy;
+extern gboolean sgen_try_free_some_memory;
 
 extern LOCK_DECLARE (gc_mutex);
 
@@ -985,6 +1002,7 @@ typedef enum {
        ATYPE_NORMAL,
        ATYPE_VECTOR,
        ATYPE_SMALL,
+       ATYPE_STRING,
        ATYPE_NUM
 } SgenAllocatorType;
 
@@ -997,6 +1015,7 @@ gboolean sgen_has_managed_allocator (void);
 /* Debug support */
 
 void sgen_check_consistency (void);
+void sgen_check_mod_union_consistency (void);
 void sgen_check_major_refs (void);
 void sgen_check_whole_heap (gboolean allow_missing_pinning);
 void sgen_check_whole_heap_stw (void) MONO_INTERNAL;
@@ -1023,6 +1042,18 @@ sgen_dummy_use (gpointer v) {
 #endif
 }
 
+/* Environment variable parsing */
+
+#define MONO_GC_PARAMS_NAME    "MONO_GC_PARAMS"
+#define MONO_GC_DEBUG_NAME     "MONO_GC_DEBUG"
+
+gboolean sgen_parse_environment_string_extract_number (const char *str, glong *out) MONO_INTERNAL;
+void sgen_env_var_error (const char *env_var, const char *fallback, const char *description_format, ...) MONO_INTERNAL;
+
+/* Utilities */
+
+void sgen_qsort (void *base, size_t nel, size_t width, int (*compar) (const void*, const void*)) MONO_INTERNAL;
+
 #endif /* HAVE_SGEN_GC */
 
 #endif /* __MONO_SGENGC_H__ */