X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fsgen%2Fsgen-gc.h;h=4b2f895d890badc5f42157ebe4009f57211ad1b4;hb=9e17248c03a49708bd1e60fec0e2cdb0684f378b;hp=4cb4edf8bafe8ed5956e2a40c4f4cd72d332fad9;hpb=bc9d5d113ab7064fc199a2f430751643466cb477;p=mono.git diff --git a/mono/sgen/sgen-gc.h b/mono/sgen/sgen-gc.h index 4cb4edf8baf..4b2f895d890 100644 --- a/mono/sgen/sgen-gc.h +++ b/mono/sgen/sgen-gc.h @@ -39,7 +39,8 @@ typedef struct _SgenThreadInfo SgenThreadInfo; #include #include "mono/utils/mono-compiler.h" #include "mono/utils/atomic.h" -#include "mono/utils/mono-mutex.h" +#include "mono/utils/mono-os-mutex.h" +#include "mono/utils/mono-coop-mutex.h" #include "mono/sgen/sgen-conf.h" #include "mono/sgen/sgen-hash-table.h" #include "mono/sgen/sgen-protocol.h" @@ -89,23 +90,14 @@ 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)) -#define LOCK_GC do { \ - MONO_TRY_BLOCKING \ - mono_mutex_lock (&gc_mutex); \ - MONO_FINISH_TRY_BLOCKING \ - } while (0) +#define LOCK_INIT(name) mono_os_mutex_init (&(name)) +#define LOCK_GC do { sgen_gc_lock (); } while (0) #define UNLOCK_GC do { sgen_gc_unlock (); } while (0) -extern LOCK_DECLARE (sgen_interruption_mutex); - -#define LOCK_INTERRUPTION do { \ - MONO_TRY_BLOCKING \ - mono_mutex_lock (&sgen_interruption_mutex); \ - MONO_FINISH_TRY_BLOCKING \ -} while (0) +extern MonoCoopMutex sgen_interruption_mutex; -#define UNLOCK_INTERRUPTION mono_mutex_unlock (&sgen_interruption_mutex) +#define LOCK_INTERRUPTION mono_coop_mutex_lock (&sgen_interruption_mutex) +#define UNLOCK_INTERRUPTION mono_coop_mutex_unlock (&sgen_interruption_mutex) /* FIXME: Use InterlockedAdd & InterlockedAdd64 to reduce the CAS cost. */ #define SGEN_CAS InterlockedCompareExchange @@ -154,12 +146,16 @@ extern int current_collection_generation; extern unsigned int sgen_global_stop_count; +#define SGEN_ALIGN_UP_TO(val,align) (((val) + (align - 1)) & ~(align - 1)) +#define SGEN_ALIGN_DOWN_TO(val,align) ((val) & ~(align - 1)) + #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)) +#define SGEN_ALIGN_UP(s) SGEN_ALIGN_UP_TO(s, SGEN_ALLOC_ALIGN) +#define SGEN_ALIGN_DOWN(s) SGEN_ALIGN_DOWN_TO(s, SGEN_ALLOC_ALIGN) #if SIZEOF_VOID_P == 4 #define ONE_P 1 @@ -245,8 +241,8 @@ sgen_get_nursery_end (void) #define SGEN_POINTER_UNTAG_VTABLE(p) SGEN_POINTER_UNTAG_ALL((p)) /* returns NULL if not forwarded, or the forwarded address */ -#define SGEN_VTABLE_IS_FORWARDED(vtable) (SGEN_POINTER_IS_TAGGED_FORWARDED ((vtable)) ? SGEN_POINTER_UNTAG_VTABLE ((vtable)) : NULL) -#define SGEN_OBJECT_IS_FORWARDED(obj) (SGEN_VTABLE_IS_FORWARDED (((mword*)(obj))[0])) +#define SGEN_VTABLE_IS_FORWARDED(vtable) ((GCVTable *)(SGEN_POINTER_IS_TAGGED_FORWARDED ((vtable)) ? SGEN_POINTER_UNTAG_VTABLE ((vtable)) : NULL)) +#define SGEN_OBJECT_IS_FORWARDED(obj) ((GCObject *)SGEN_VTABLE_IS_FORWARDED (((mword*)(obj))[0])) #define SGEN_VTABLE_IS_PINNED(vtable) SGEN_POINTER_IS_TAGGED_PINNED ((vtable)) #define SGEN_OBJECT_IS_PINNED(obj) (SGEN_VTABLE_IS_PINNED (((mword*)(obj))[0])) @@ -272,7 +268,7 @@ sgen_get_nursery_end (void) * Since we set bits in the vtable, use the macro to load it from the pointer to * an object that is potentially pinned. */ -#define SGEN_LOAD_VTABLE(obj) ((GCVTable)(SGEN_POINTER_UNTAG_ALL (SGEN_LOAD_VTABLE_UNCHECKED ((obj))))) +#define SGEN_LOAD_VTABLE(obj) ((GCVTable)(SGEN_POINTER_UNTAG_ALL (SGEN_LOAD_VTABLE_UNCHECKED ((GCObject *)(obj))))) /* List of what each bit on of the vtable gc bits means. @@ -411,11 +407,14 @@ gboolean sgen_is_worker_thread (MonoNativeThreadId thread); typedef void (*CopyOrMarkObjectFunc) (GCObject**, SgenGrayQueue*); typedef void (*ScanObjectFunc) (GCObject *obj, SgenDescriptor desc, SgenGrayQueue*); typedef void (*ScanVTypeFunc) (GCObject *full_object, char *start, SgenDescriptor desc, SgenGrayQueue* BINARY_PROTOCOL_ARG (size_t size)); +typedef gboolean (*DrainGrayStackFunc) (SgenGrayQueue *queue); typedef struct { CopyOrMarkObjectFunc copy_or_mark_object; ScanObjectFunc scan_object; ScanVTypeFunc scan_vtype; + /* Drain stack optimized for the above functions */ + DrainGrayStackFunc drain_gray_stack; /*FIXME add allocation function? */ } SgenObjectOperations; @@ -446,7 +445,7 @@ void sgen_pin_stats_register_global_remset (GCObject *obj); void sgen_pin_stats_print_class_stats (void); void sgen_sort_addresses (void **array, size_t size); -void sgen_add_to_global_remset (gpointer ptr, gpointer obj); +void sgen_add_to_global_remset (gpointer ptr, GCObject *obj); int sgen_get_current_collection_generation (void); gboolean sgen_collection_is_concurrent (void); @@ -604,13 +603,6 @@ struct _SgenMajorCollector { gboolean supports_cardtable; gboolean sweeps_lazily; - /* - * This is set to TRUE by the sweep if the next major - * collection should be synchronous (for evacuation). For - * non-concurrent collectors, this should be NULL. - */ - gboolean *want_synchronous_collection; - void* (*alloc_heap) (mword nursery_size, mword nursery_align, int nursery_bits); gboolean (*is_object_live) (GCObject *obj); GCObject* (*alloc_small_pinned_obj) (GCVTable vtable, size_t size, gboolean has_references); @@ -618,7 +610,6 @@ struct _SgenMajorCollector { SgenObjectOperations major_ops_serial; SgenObjectOperations major_ops_concurrent_start; - SgenObjectOperations major_ops_concurrent; SgenObjectOperations major_ops_concurrent_finish; GCObject* (*alloc_object) (GCVTable vtable, size_t size, gboolean has_references); @@ -648,7 +639,6 @@ struct _SgenMajorCollector { void (*finish_nursery_collection) (void); void (*start_major_collection) (void); void (*finish_major_collection) (ScannedObjectCounts *counts); - gboolean (*drain_gray_stack) (ScanCopyContext ctx); gboolean (*ptr_is_in_non_pinned_space) (char *ptr, char **start); gboolean (*ptr_is_from_pinned_alloc) (char *ptr); void (*report_pinned_memory_usage) (void); @@ -801,7 +791,7 @@ void sgen_register_disappearing_link (GCObject *obj, void **link, gboolean track GCObject* sgen_weak_link_get (void **link_addr); -gboolean sgen_drain_gray_stack (int max_objs, ScanCopyContext ctx); +gboolean sgen_drain_gray_stack (ScanCopyContext ctx); enum { SPACE_NURSERY, @@ -812,7 +802,7 @@ enum { void sgen_pin_object (GCObject *object, SgenGrayQueue *queue); void sgen_set_pinned_from_failed_allocation (mword objsize); -void sgen_ensure_free_space (size_t size); +void sgen_ensure_free_space (size_t size, int generation); void sgen_gc_collect (int generation); void sgen_perform_collection (size_t requested_size, int generation_to_collect, const char *reason, gboolean wait_to_finish); @@ -965,7 +955,7 @@ extern guint32 tlab_size; extern NurseryClearPolicy nursery_clear_policy; extern gboolean sgen_try_free_some_memory; -extern LOCK_DECLARE (gc_mutex); +extern MonoCoopMutex gc_mutex; /* Nursery helpers. */