#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;
#endif
+static gboolean global_remset_location_was_not_added (gpointer ptr);
+
+
static void
clear_thread_store_remset_buffer (SgenThreadInfo *info)
{
-void
+static void
mono_sgen_ssb_wbarrier_set_field (MonoObject *obj, gpointer field_ptr, MonoObject* value)
{
RememberedSet *rs;
UNLOCK_GC;
}
-void
+static void
mono_sgen_ssb_wbarrier_set_arrayref (MonoArray *arr, gpointer slot_ptr, MonoObject* value)
{
RememberedSet *rs;
UNLOCK_GC;
}
-void
+static void
mono_sgen_ssb_wbarrier_arrayref_copy (gpointer dest_ptr, gpointer src_ptr, int count)
{
RememberedSet *rs;
UNLOCK_GC;
}
-void
+static void
mono_sgen_ssb_wbarrier_value_copy (gpointer dest, gpointer src, int count, MonoClass *klass)
{
RememberedSet *rs;
UNLOCK_GC;
}
-void
+static void
mono_sgen_ssb_wbarrier_object_copy (MonoObject* obj, MonoObject *src)
{
int size;
UNLOCK_GC;
}
-void
+static void
mono_sgen_ssb_wbarrier_generic_nostore (gpointer ptr)
{
gpointer *buffer;
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
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;
}
}
-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;
}
-void
+static void
mono_sgen_ssb_cleanup_thread (SgenThreadInfo *p)
{
RememberedSet *rset;
*p->store_remset_buffer_addr = NULL;
}
-void
+static void
mono_sgen_ssb_register_thread (SgenThreadInfo *info)
{
#ifndef HAVE_KW_THREAD
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));
* 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;
*
* Returns TRUE is the element was added..
*/
-gboolean
+static gboolean
global_remset_location_was_not_added (gpointer ptr)
{
return TRUE;
}
-void
+static void
mono_sgen_ssb_record_pointer (gpointer ptr)
{
RememberedSet *rs;
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);
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