X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=mono%2Fmetadata%2Fsgen-ssb.c;h=65f0c6da55349dbeec632934bffbd5f31797c1c0;hb=12c99202fa08e7b128ba234d7b3bac722eb3aab8;hp=031ade85becd93302bc1d54ff4fe53d03b3a8931;hpb=284b8b6a50c80a2513eed411084eebe5b2bd5ac4;p=mono.git diff --git a/mono/metadata/sgen-ssb.c b/mono/metadata/sgen-ssb.c index 031ade85bec..65f0c6da553 100644 --- a/mono/metadata/sgen-ssb.c +++ b/mono/metadata/sgen-ssb.c @@ -47,12 +47,12 @@ static LOCK_DECLARE (global_remset_mutex); #define UNLOCK_GLOBAL_REMSET mono_mutex_unlock (&global_remset_mutex) #ifdef HAVE_KW_THREAD -__thread RememberedSet *remembered_set MONO_TLS_FAST; +static __thread RememberedSet *remembered_set MONO_TLS_FAST; #endif static MonoNativeTlsKey remembered_set_key; -RememberedSet *global_remset; -RememberedSet *freed_thread_remsets; -GenericStoreRememberedSet *generic_store_remsets = NULL; +static RememberedSet *global_remset; +static RememberedSet *freed_thread_remsets; +static GenericStoreRememberedSet *generic_store_remsets = NULL; #ifdef HEAVY_STATISTICS static int stat_wbarrier_generic_store_remset = 0; @@ -69,6 +69,9 @@ static long long stat_global_remsets_discarded = 0; #endif +static gboolean global_remset_location_was_not_added (gpointer ptr); + + static void clear_thread_store_remset_buffer (SgenThreadInfo *info) { @@ -123,7 +126,7 @@ mono_sgen_alloc_remset (int size, gpointer id, gboolean global) -void +static void mono_sgen_ssb_wbarrier_set_field (MonoObject *obj, gpointer field_ptr, MonoObject* value) { RememberedSet *rs; @@ -148,7 +151,7 @@ mono_sgen_ssb_wbarrier_set_field (MonoObject *obj, gpointer field_ptr, MonoObjec UNLOCK_GC; } -void +static void mono_sgen_ssb_wbarrier_set_arrayref (MonoArray *arr, gpointer slot_ptr, MonoObject* value) { RememberedSet *rs; @@ -173,7 +176,7 @@ mono_sgen_ssb_wbarrier_set_arrayref (MonoArray *arr, gpointer slot_ptr, MonoObje UNLOCK_GC; } -void +static void mono_sgen_ssb_wbarrier_arrayref_copy (gpointer dest_ptr, gpointer src_ptr, int count) { RememberedSet *rs; @@ -201,7 +204,7 @@ mono_sgen_ssb_wbarrier_arrayref_copy (gpointer dest_ptr, gpointer src_ptr, int c UNLOCK_GC; } -void +static void mono_sgen_ssb_wbarrier_value_copy (gpointer dest, gpointer src, int count, MonoClass *klass) { RememberedSet *rs; @@ -236,7 +239,7 @@ mono_sgen_ssb_wbarrier_value_copy (gpointer dest, gpointer src, int count, MonoC UNLOCK_GC; } -void +static void mono_sgen_ssb_wbarrier_object_copy (MonoObject* obj, MonoObject *src) { int size; @@ -269,7 +272,7 @@ mono_sgen_ssb_wbarrier_object_copy (MonoObject* obj, MonoObject *src) UNLOCK_GC; } -void +static void mono_sgen_ssb_wbarrier_generic_nostore (gpointer ptr) { gpointer *buffer; @@ -415,7 +418,7 @@ handle_remset (mword *p, void *start_nursery, void *end_nursery, gboolean global major_collector.copy_object (ptr, queue); DEBUG (9, fprintf (gc_debug_file, "Overwrote remset at %p with %p\n", ptr, *ptr)); if (old) - binary_protocol_ptr_update (ptr, old, *ptr, (gpointer)LOAD_VTABLE (*ptr), safe_object_get_size (*ptr)); + binary_protocol_ptr_update (ptr, old, *ptr, (gpointer)LOAD_VTABLE (*ptr), mono_sgen_safe_object_get_size (*ptr)); if (!global && *ptr >= start_nursery && *ptr < end_nursery) { /* * If the object is pinned, each reference to it from nonpinned objects @@ -469,8 +472,8 @@ handle_remset (mword *p, void *start_nursery, void *end_nursery, gboolean global return NULL; } -void -mono_sgen_ssb_scan_from_global_remsets (void *start_nursery, void *end_nursery, SgenGrayQueue *queue) +static void +mono_sgen_ssb_begin_scan_remsets (void *start_nursery, void *end_nursery, SgenGrayQueue *queue) { RememberedSet *remset; mword *p, *next_p, *store_pos; @@ -508,8 +511,8 @@ mono_sgen_ssb_scan_from_global_remsets (void *start_nursery, void *end_nursery, } } -void -mono_sgen_ssb_scan_from_remsets (void *start_nursery, void *end_nursery, SgenGrayQueue *queue) +static void +mono_sgen_ssb_finish_scan_remsets (void *start_nursery, void *end_nursery, SgenGrayQueue *queue) { int i; SgenThreadInfo *info; @@ -574,7 +577,7 @@ mono_sgen_ssb_scan_from_remsets (void *start_nursery, void *end_nursery, SgenGra } -void +static void mono_sgen_ssb_cleanup_thread (SgenThreadInfo *p) { RememberedSet *rset; @@ -606,7 +609,7 @@ mono_sgen_ssb_cleanup_thread (SgenThreadInfo *p) *p->store_remset_buffer_addr = NULL; } -void +static void mono_sgen_ssb_register_thread (SgenThreadInfo *info) { #ifndef HAVE_KW_THREAD @@ -623,7 +626,16 @@ mono_sgen_ssb_register_thread (SgenThreadInfo *info) STORE_REMSET_BUFFER_INDEX = 0; } -void +#ifdef HAVE_KW_THREAD +static void +mono_sgen_ssb_fill_thread_info_for_suspend (SgenThreadInfo *info) +{ + /* update the remset info in the thread data structure */ + info->remset = remembered_set; +} +#endif + +static void mono_sgen_ssb_prepare_for_minor_collection (void) { memset (global_remset_cache, 0, sizeof (global_remset_cache)); @@ -634,7 +646,7 @@ mono_sgen_ssb_prepare_for_minor_collection (void) * the per-thread ones are not needed and the global ones will be reconstructed * during the copy. */ -void +static void mono_sgen_ssb_prepare_for_major_collection (void) { SgenThreadInfo *info; @@ -692,7 +704,7 @@ mono_sgen_ssb_prepare_for_major_collection (void) * * Returns TRUE is the element was added.. */ -gboolean +static gboolean global_remset_location_was_not_added (gpointer ptr) { @@ -718,7 +730,7 @@ global_remset_location_was_not_added (gpointer ptr) return TRUE; } -void +static void mono_sgen_ssb_record_pointer (gpointer ptr) { RememberedSet *rs; @@ -768,8 +780,120 @@ mono_sgen_ssb_record_pointer (gpointer ptr) UNLOCK_GLOBAL_REMSET; } +/* + * ###################################################################### + * ######## Debug support + * ###################################################################### + */ + +static mword* +find_in_remset_loc (mword *p, char *addr, gboolean *found) +{ + void **ptr; + mword count, desc; + size_t skip_size; + + switch ((*p) & REMSET_TYPE_MASK) { + case REMSET_LOCATION: + if (*p == (mword)addr) + *found = TRUE; + return p + 1; + case REMSET_RANGE: + ptr = (void**)(*p & ~REMSET_TYPE_MASK); + count = p [1]; + if ((void**)addr >= ptr && (void**)addr < ptr + count) + *found = TRUE; + return p + 2; + case REMSET_OBJECT: + ptr = (void**)(*p & ~REMSET_TYPE_MASK); + count = mono_sgen_safe_object_get_size ((MonoObject*)ptr); + count = SGEN_ALIGN_UP (count); + count /= sizeof (mword); + if ((void**)addr >= ptr && (void**)addr < ptr + count) + *found = TRUE; + return p + 1; + case REMSET_VTYPE: + ptr = (void**)(*p & ~REMSET_TYPE_MASK); + desc = p [1]; + count = p [2]; + skip_size = p [3]; + + /* The descriptor includes the size of MonoObject */ + skip_size -= sizeof (MonoObject); + skip_size *= count; + if ((void**)addr >= ptr && (void**)addr < ptr + (skip_size / sizeof (gpointer))) + *found = TRUE; + + return p + 4; + default: + g_assert_not_reached (); + } + return NULL; +} +/* + * Return whenever ADDR occurs in the remembered sets + */ +static gboolean +mono_sgen_ssb_find_address (char *addr) +{ + int i; + SgenThreadInfo *info; + RememberedSet *remset; + GenericStoreRememberedSet *store_remset; + mword *p; + gboolean found = FALSE; + + /* the global one */ + for (remset = global_remset; remset; remset = remset->next) { + DEBUG (4, fprintf (gc_debug_file, "Scanning global remset range: %p-%p, size: %td\n", remset->data, remset->store_next, remset->store_next - remset->data)); + for (p = remset->data; p < remset->store_next;) { + p = find_in_remset_loc (p, addr, &found); + if (found) + return TRUE; + } + } + + /* the generic store ones */ + for (store_remset = generic_store_remsets; store_remset; store_remset = store_remset->next) { + for (i = 0; i < STORE_REMSET_BUFFER_SIZE - 1; ++i) { + if (store_remset->data [i] == addr) + return TRUE; + } + } + + /* the per-thread ones */ + FOREACH_THREAD (info) { + int j; + for (remset = info->remset; remset; remset = remset->next) { + DEBUG (4, fprintf (gc_debug_file, "Scanning remset for thread %p, range: %p-%p, size: %td\n", info, remset->data, remset->store_next, remset->store_next - remset->data)); + for (p = remset->data; p < remset->store_next;) { + p = find_in_remset_loc (p, addr, &found); + if (found) + return TRUE; + } + } + for (j = 0; j < *info->store_remset_buffer_index_addr; ++j) { + if ((*info->store_remset_buffer_addr) [j + 1] == addr) + return TRUE; + } + } END_FOREACH_THREAD + + /* the freed thread ones */ + for (remset = freed_thread_remsets; remset; remset = remset->next) { + DEBUG (4, fprintf (gc_debug_file, "Scanning remset for freed thread, range: %p-%p, size: %td\n", remset->data, remset->store_next, remset->store_next - remset->data)); + for (p = remset->data; p < remset->store_next;) { + p = find_in_remset_loc (p, addr, &found); + if (found) + return TRUE; + } + } + + return FALSE; +} + + void -mono_sgen_ssb_init (void) +mono_sgen_ssb_init (SgenRemeberedSet *remset) { LOCK_INIT (global_remset_mutex); @@ -791,6 +915,27 @@ mono_sgen_ssb_init (void) mono_counters_register ("Global remsets processed", MONO_COUNTER_GC | MONO_COUNTER_LONG, &stat_global_remsets_processed); mono_counters_register ("Global remsets discarded", MONO_COUNTER_GC | MONO_COUNTER_LONG, &stat_global_remsets_discarded); #endif -} + remset->wbarrier_set_field = mono_sgen_ssb_wbarrier_set_field; + remset->wbarrier_set_arrayref = mono_sgen_ssb_wbarrier_set_arrayref; + remset->wbarrier_arrayref_copy = mono_sgen_ssb_wbarrier_arrayref_copy; + remset->wbarrier_value_copy = mono_sgen_ssb_wbarrier_value_copy; + remset->wbarrier_object_copy = mono_sgen_ssb_wbarrier_object_copy; + remset->wbarrier_generic_nostore = mono_sgen_ssb_wbarrier_generic_nostore; + remset->record_pointer = mono_sgen_ssb_record_pointer; + + remset->begin_scan_remsets = mono_sgen_ssb_begin_scan_remsets; + remset->finish_scan_remsets = mono_sgen_ssb_finish_scan_remsets; + + remset->register_thread = mono_sgen_ssb_register_thread; + remset->cleanup_thread = mono_sgen_ssb_cleanup_thread; +#ifdef HAVE_KW_THREAD + remset->fill_thread_info_for_suspend = mono_sgen_ssb_fill_thread_info_for_suspend; +#endif + + remset->prepare_for_minor_collection = mono_sgen_ssb_prepare_for_minor_collection; + remset->prepare_for_major_collection = mono_sgen_ssb_prepare_for_major_collection; + + remset->find_address = mono_sgen_ssb_find_address; +} #endif