if (!array_fill_vtable) {
static MonoClass klass;
static char _vtable[sizeof(MonoVTable)+8];
- MonoVTable* vtable = (MonoVTable*) ALIGN_TO(_vtable, 8);
+ MonoVTable* vtable = (MonoVTable*) ALIGN_TO((mword)_vtable, 8);
gsize bmap;
MonoDomain *domain = mono_get_root_domain ();
FOREACH_THREAD (info) {
int skip_reason = 0;
+ void *aligned_stack_start = (void*)(mword) ALIGN_TO ((mword)info->client_info.stack_start, SIZEOF_VOID_P);
+
if (info->client_info.skip) {
SGEN_LOG (3, "Skipping dead thread %p, range: %p-%p, size: %zd", info, info->client_info.stack_start, info->client_info.stack_end, (char*)info->client_info.stack_end - (char*)info->client_info.stack_start);
skip_reason = 1;
g_assert (info->client_info.suspend_done);
SGEN_LOG (3, "Scanning thread %p, range: %p-%p, size: %zd, pinned=%zd", info, info->client_info.stack_start, info->client_info.stack_end, (char*)info->client_info.stack_end - (char*)info->client_info.stack_start, sgen_get_pinned_count ());
if (mono_gc_get_gc_callbacks ()->thread_mark_func && !conservative_stack_mark) {
- mono_gc_get_gc_callbacks ()->thread_mark_func (info->client_info.runtime_data, info->client_info.stack_start, info->client_info.stack_end, precise, &ctx);
+ mono_gc_get_gc_callbacks ()->thread_mark_func (info->client_info.runtime_data, aligned_stack_start, info->client_info.stack_end, precise, &ctx);
} else if (!precise) {
if (!conservative_stack_mark) {
fprintf (stderr, "Precise stack mark not supported - disabling.\n");
conservative_stack_mark = TRUE;
}
- sgen_conservatively_pin_objects_from (info->client_info.stack_start, info->client_info.stack_end, start_nursery, end_nursery, PIN_TYPE_STACK);
+ sgen_conservatively_pin_objects_from (aligned_stack_start, info->client_info.stack_end, start_nursery, end_nursery, PIN_TYPE_STACK);
}
if (!precise) {
sgen_conservatively_pin_objects_from ((void**)&info->client_info.regs, (void**)&info->client_info.regs + ARCH_NUM_REGS,
start_nursery, end_nursery, PIN_TYPE_STACK);
#endif
+ {
+ // This is used on Coop GC for platforms where we cannot get the data for individual registers.
+ // We force a spill of all registers into the stack and pass a chunk of data into sgen.
+ MonoThreadUnwindState *state = mono_thread_info_get_suspend_state (info);
+ if (state && state->gc_stackdata) {
+ sgen_conservatively_pin_objects_from (state->gc_stackdata, (void**)((char*)state->gc_stackdata + state->gc_stackdata_size),
+ start_nursery, end_nursery, PIN_TYPE_STACK);
+ }
+ }
}
} END_FOREACH_THREAD
}
return SGEN_MAX_SMALL_OBJ_SIZE;
}
-void
-mono_gc_weak_link_register (volatile gpointer *link_addr, MonoObject *obj, gboolean track)
-{
- binary_protocol_dislink_add ((gpointer)link_addr, obj, track);
-}
-
-void
-mono_gc_weak_link_unregister (volatile gpointer *link_addr, gboolean track)
-{
- binary_protocol_dislink_remove ((gpointer)link_addr, track);
-}
-
-void
-mono_gc_ensure_weak_links_accessible (void)
-{
- /*
- * 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.
- */
- /* FIXME: A GC can occur after this check fails, in which case we
- * should wait for bridge processing but would fail to do so.
- */
- mono_gc_wait_for_bridge_processing ();
-}
-
gpointer
sgen_client_default_metadata (void)
{