{
int count = 0;
+ SGEN_ASSERT (0, ((mword)start & (SIZEOF_VOID_P - 1)) == 0, "Why are we scanning for references in unaligned memory ?");
+
#if defined(VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE) && !defined(_WIN64)
VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE (start, (char*)end - (char*)start);
#endif
We must clear weak links that don't track resurrection before processing object ready for
finalization so they can be cleared before that.
*/
- sgen_null_link_in_range (generation, TRUE, ctx);
+ sgen_null_link_in_range (generation, ctx, FALSE);
if (generation == GENERATION_OLD)
- sgen_null_link_in_range (GENERATION_NURSERY, TRUE, ctx);
+ sgen_null_link_in_range (GENERATION_NURSERY, ctx, FALSE);
/* walk the finalization queue and move also the objects that need to be
*/
g_assert (sgen_gray_object_queue_is_empty (queue));
for (;;) {
- sgen_null_link_in_range (generation, FALSE, ctx);
+ sgen_null_link_in_range (generation, ctx, TRUE);
if (generation == GENERATION_OLD)
- sgen_null_link_in_range (GENERATION_NURSERY, FALSE, ctx);
+ sgen_null_link_in_range (GENERATION_NURSERY, ctx, TRUE);
if (sgen_gray_object_queue_is_empty (queue))
break;
sgen_drain_gray_stack (-1, ctx);
sgen_check_consistency ();
sgen_process_fin_stage_entries ();
- sgen_process_dislink_stage_entries ();
/* pin from pinned handles */
sgen_init_pinning ();
}
sgen_process_fin_stage_entries ();
- sgen_process_dislink_stage_entries ();
TV_GETTIME (atv);
sgen_init_pinning ();
fragment_total = sgen_build_nursery_fragments (nursery_section, NULL);
if (!fragment_total)
degraded_mode = 1;
- SGEN_LOG (4, "Free space in nursery after major %ld", fragment_total);
+ SGEN_LOG (4, "Free space in nursery after major %ld", (long)fragment_total);
if (do_concurrent_checks && concurrent_collection_in_progress)
sgen_debug_check_nursery_is_clean ();
major_finish_concurrent_collection (wait_to_finish);
oldest_generation_collected = GENERATION_OLD;
} else {
- sgen_workers_signal_start_nursery_collection_and_wait ();
-
major_update_concurrent_collection ();
if (generation_to_collect == GENERATION_NURSERY)
collect_nursery (NULL, FALSE);
-
- sgen_workers_signal_finish_nursery_collection ();
}
goto done;
* We do not coalesce roots.
*/
int
-sgen_register_root (char *start, size_t size, SgenDescriptor descr, int root_type)
+sgen_register_root (char *start, size_t size, SgenDescriptor descr, int root_type, int source, const char *msg)
{
RootRecord new_root;
int i;
size_t old_size = root->end_root - start;
root->end_root = start + size;
SGEN_ASSERT (0, !!root->root_desc == !!descr, "Can't change whether a root is precise or conservative.");
+ SGEN_ASSERT (0, root->source == source, "Can't change a root's source identifier.");
+ SGEN_ASSERT (0, !!root->msg == !!msg, "Can't change a root's message.");
root->root_desc = descr;
roots_size += size;
roots_size -= old_size;
new_root.end_root = start + size;
new_root.root_desc = descr;
+ new_root.source = source;
+ new_root.msg = msg;
sgen_hash_table_replace (&roots_hash [root_type], start, &new_root, NULL);
roots_size += size;
- SGEN_LOG (3, "Added root for range: %p-%p, descr: %llx (%d/%d bytes)", start, new_root.end_root, descr, (int)size, (int)roots_size);
+ SGEN_LOG (3, "Added root for range: %p-%p, descr: %llx (%d/%d bytes)", start, new_root.end_root, (long long)descr, (int)size, (int)roots_size);
UNLOCK_GC;
return TRUE;
return tot;
}
-GCObject*
-sgen_weak_link_get (void **link_addr)
-{
- void * volatile *link_addr_volatile;
- void *ptr;
- GCObject *obj;
- retry:
- link_addr_volatile = link_addr;
- ptr = (void*)*link_addr_volatile;
- /*
- * At this point we have a hidden pointer. If the GC runs
- * here, it will not recognize the hidden pointer as a
- * reference, and if the object behind it is not referenced
- * elsewhere, it will be freed. Once the world is restarted
- * we reveal the pointer, giving us a pointer to a freed
- * object. To make sure we don't return it, we load the
- * hidden pointer again. If it's still the same, we can be
- * sure the object reference is valid.
- */
- if (ptr)
- obj = (GCObject*) REVEAL_POINTER (ptr);
- else
- return NULL;
-
- mono_memory_barrier ();
-
- /*
- * During the second bridge processing step the world is
- * running again. That step processes all weak links once
- * more to null those that refer to dead objects. Before that
- * is completed, those links must not be followed, so we
- * conservatively wait for bridge processing when any weak
- * link is dereferenced.
- */
- sgen_client_bridge_wait_for_processing ();
-
- if ((void*)*link_addr_volatile != ptr)
- goto retry;
-
- return obj;
-}
-
gboolean
sgen_set_allow_synchronous_major (gboolean flag)
{
sgen_init_descriptors ();
sgen_init_gray_queues ();
sgen_init_allocator ();
+ sgen_init_gchandles ();
sgen_register_fixed_internal_mem_type (INTERNAL_MEM_SECTION, SGEN_SIZEOF_GC_MEM_SECTION);
sgen_register_fixed_internal_mem_type (INTERNAL_MEM_GRAY_QUEUE, sizeof (GrayQueueSection));
sgen_card_table_init (&remset);
+ sgen_register_root (NULL, 0, sgen_make_user_root_descriptor (sgen_mark_normal_gc_handles), ROOT_TYPE_NORMAL, MONO_ROOT_SOURCE_GC_HANDLE, "normal gc handles");
+
gc_initialized = 1;
}