[runtime] Add MonoError to mono_remote_class
[mono.git] / mono / metadata / sgen-mono.c
index bb06f7eec0273cf41821d64e82c7c4c77bebffb6..8421b903ba6f967366bba0f2d7c7b337510ac1ee 100644 (file)
 #include "metadata/abi-details.h"
 #include "metadata/mono-gc.h"
 #include "metadata/runtime.h"
-#include "metadata/sgen-bridge-internal.h"
-#include "metadata/gc-internal.h"
+#include "metadata/sgen-bridge-internals.h"
+#include "metadata/gc-internals.h"
+#include "metadata/handle.h"
 #include "utils/mono-memory-model.h"
-#include "utils/mono-logger-internal.h"
+#include "utils/mono-logger-internals.h"
 
 #ifdef HEAVY_STATISTICS
 static guint64 stat_wbarrier_set_arrayref = 0;
@@ -220,12 +221,14 @@ emit_nursery_check (MonoMethodBuilder *mb, int *nursery_check_return_labels, gbo
         */
        mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
        mono_mb_emit_byte (mb, CEE_MONO_LDPTR_NURSERY_START);
-       mono_mb_emit_icon (mb, DEFAULT_NURSERY_BITS);
+       mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+       mono_mb_emit_byte (mb, CEE_MONO_LDPTR_NURSERY_BITS);
        mono_mb_emit_byte (mb, CEE_SHR_UN);
        mono_mb_emit_stloc (mb, shifted_nursery_start);
 
        mono_mb_emit_ldarg (mb, 0);
-       mono_mb_emit_icon (mb, DEFAULT_NURSERY_BITS);
+       mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+       mono_mb_emit_byte (mb, CEE_MONO_LDPTR_NURSERY_BITS);
        mono_mb_emit_byte (mb, CEE_SHR_UN);
        mono_mb_emit_ldloc (mb, shifted_nursery_start);
        nursery_check_return_labels [0] = mono_mb_emit_branch (mb, CEE_BEQ);
@@ -234,7 +237,8 @@ emit_nursery_check (MonoMethodBuilder *mb, int *nursery_check_return_labels, gbo
                // if (!ptr_in_nursery (*ptr)) return;
                mono_mb_emit_ldarg (mb, 0);
                mono_mb_emit_byte (mb, CEE_LDIND_I);
-               mono_mb_emit_icon (mb, DEFAULT_NURSERY_BITS);
+               mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+               mono_mb_emit_byte (mb, CEE_MONO_LDPTR_NURSERY_BITS);
                mono_mb_emit_byte (mb, CEE_SHR_UN);
                mono_mb_emit_ldloc (mb, shifted_nursery_start);
                nursery_check_return_labels [1] = mono_mb_emit_branch (mb, CEE_BNE_UN);
@@ -249,6 +253,7 @@ mono_gc_get_specific_write_barrier (gboolean is_concurrent)
        MonoMethodBuilder *mb;
        MonoMethodSignature *sig;
        MonoMethod **write_barrier_method_addr;
+       WrapperInfo *info;
 #ifdef MANAGED_WBARRIER
        int i, nursery_check_labels [2];
 #endif
@@ -327,6 +332,8 @@ mono_gc_get_specific_write_barrier (gboolean is_concurrent)
 #endif
 #endif
        res = mono_mb_create_method (mb, sig, 16);
+       info = mono_wrapper_info_create (mb, WRAPPER_SUBTYPE_NONE);
+       mono_marshal_set_wrapper_info (res, info);
        mono_mb_free (mb);
 
        LOCK_GC;
@@ -370,7 +377,7 @@ get_array_fill_vtable (void)
 
                klass.element_class = mono_defaults.byte_class;
                klass.rank = 1;
-               klass.instance_size = sizeof (MonoArray);
+               klass.instance_size = MONO_SIZEOF_MONO_ARRAY;
                klass.sizes.element_size = 1;
                klass.name = "array_filler_type";
 
@@ -389,7 +396,7 @@ sgen_client_array_fill_range (char *start, size_t size)
 {
        MonoArray *o;
 
-       if (size < sizeof (MonoArray)) {
+       if (size < MONO_SIZEOF_MONO_ARRAY) {
                memset (start, 0, size);
                return FALSE;
        }
@@ -397,9 +404,9 @@ sgen_client_array_fill_range (char *start, size_t size)
        o = (MonoArray*)start;
        o->obj.vtable = (MonoVTable*)get_array_fill_vtable ();
        /* Mark this as not a real object */
-       o->obj.synchronisation = GINT_TO_POINTER (-1);
+       o->obj.synchronisation = (MonoThreadsSync *)GINT_TO_POINTER (-1);
        o->bounds = NULL;
-       o->max_length = (mono_array_size_t)(size - sizeof (MonoArray));
+       o->max_length = (mono_array_size_t)(size - MONO_SIZEOF_MONO_ARRAY);
 
        return TRUE;
 }
@@ -407,10 +414,10 @@ sgen_client_array_fill_range (char *start, size_t size)
 void
 sgen_client_zero_array_fill_header (void *p, size_t size)
 {
-       if (size >= sizeof (MonoArray)) {
-               memset (p, 0, sizeof (MonoArray));
+       if (size >= MONO_SIZEOF_MONO_ARRAY) {
+               memset (p, 0, MONO_SIZEOF_MONO_ARRAY);
        } else {
-               static guint8 zeros [sizeof (MonoArray)];
+               static guint8 zeros [MONO_SIZEOF_MONO_ARRAY];
 
                SGEN_ASSERT (0, !memcmp (p, zeros, size), "TLAB segment must be zeroed out.");
        }
@@ -423,12 +430,12 @@ sgen_client_zero_array_fill_header (void *p, size_t size)
 static MonoGCFinalizerCallbacks fin_callbacks;
 
 guint
-mono_gc_get_vtable_bits (MonoClass *class)
+mono_gc_get_vtable_bits (MonoClass *klass)
 {
        guint res = 0;
        /* FIXME move this to the bridge code */
        if (sgen_need_bridge_processing ()) {
-               switch (sgen_bridge_class_kind (class)) {
+               switch (sgen_bridge_class_kind (klass)) {
                case GC_BRIDGE_TRANSPARENT_BRIDGE_CLASS:
                case GC_BRIDGE_OPAQUE_BRIDGE_CLASS:
                        res = SGEN_GC_BIT_BRIDGE_OBJECT;
@@ -441,7 +448,7 @@ mono_gc_get_vtable_bits (MonoClass *class)
                }
        }
        if (fin_callbacks.is_class_finalization_aware) {
-               if (fin_callbacks.is_class_finalization_aware (class))
+               if (fin_callbacks.is_class_finalization_aware (klass))
                        res |= SGEN_GC_BIT_FINALIZER_AWARE;
        }
        return res;
@@ -513,7 +520,7 @@ mono_gc_register_for_finalization (MonoObject *obj, void *user_data)
 static gboolean
 object_in_domain_predicate (MonoObject *obj, void *user_data)
 {
-       MonoDomain *domain = user_data;
+       MonoDomain *domain = (MonoDomain *)user_data;
        if (mono_object_domain (obj) == domain) {
                SGEN_LOG (5, "Unregistering finalizer for object: %p (%s)", obj, sgen_client_vtable_get_name (SGEN_LOAD_VTABLE (obj)));
                return TRUE;
@@ -711,7 +718,7 @@ mono_gc_ephemeron_array_add (MonoObject *obj)
 
        LOCK_GC;
 
-       node = sgen_alloc_internal (INTERNAL_MEM_EPHEMERON_LINK);
+       node = (EphemeronLinkNode *)sgen_alloc_internal (INTERNAL_MEM_EPHEMERON_LINK);
        if (!node) {
                UNLOCK_GC;
                return FALSE;
@@ -929,8 +936,10 @@ mono_gc_alloc_obj (MonoVTable *vtable, size_t size)
 {
        MonoObject *obj = sgen_alloc_obj (vtable, size);
 
-       if (G_UNLIKELY (alloc_events))
-               mono_profiler_allocation (obj);
+       if (G_UNLIKELY (alloc_events)) {
+               if (obj)
+                       mono_profiler_allocation (obj);
+       }
 
        return obj;
 }
@@ -940,22 +949,23 @@ mono_gc_alloc_pinned_obj (MonoVTable *vtable, size_t size)
 {
        MonoObject *obj = sgen_alloc_obj_pinned (vtable, size);
 
-       if (G_UNLIKELY (alloc_events))
-               mono_profiler_allocation (obj);
+       if (G_UNLIKELY (alloc_events)) {
+               if (obj)
+                       mono_profiler_allocation (obj);
+       }
 
        return obj;
 }
 
 void*
-mono_gc_alloc_mature (MonoVTable *vtable)
+mono_gc_alloc_mature (MonoVTable *vtable, size_t size)
 {
-       MonoObject *obj = sgen_alloc_obj_mature (vtable, vtable->klass->instance_size);
+       MonoObject *obj = sgen_alloc_obj_mature (vtable, size);
 
-       if (obj && G_UNLIKELY (obj->vtable->klass->has_finalize))
-               mono_object_register_finalizer (obj);
-
-       if (G_UNLIKELY (alloc_events))
-               mono_profiler_allocation (obj);
+       if (G_UNLIKELY (alloc_events)) {
+               if (obj)
+                       mono_profiler_allocation (obj);
+       }
 
        return obj;
 }
@@ -967,7 +977,7 @@ mono_gc_alloc_fixed (size_t size, MonoGCDescriptor descr, MonoGCRootSource sourc
        void *res = calloc (1, size);
        if (!res)
                return NULL;
-       if (!mono_gc_register_root (res, size, descr, source, msg)) {
+       if (!mono_gc_register_root ((char *)res, size, descr, source, msg)) {
                free (res);
                res = NULL;
        }
@@ -977,7 +987,7 @@ mono_gc_alloc_fixed (size_t size, MonoGCDescriptor descr, MonoGCRootSource sourc
 void
 mono_gc_free_fixed (void* addr)
 {
-       mono_gc_deregister_root (addr);
+       mono_gc_deregister_root ((char *)addr);
        free (addr);
 }
 
@@ -1052,7 +1062,7 @@ create_allocator (int atype, gboolean slowpath)
        static gboolean registered = FALSE;
        int tlab_next_addr_var, new_next_var;
        const char *name = NULL;
-       AllocatorWrapperInfo *info;
+       WrapperInfo *info;
        int num_params, i;
 
        if (!registered) {
@@ -1098,16 +1108,16 @@ create_allocator (int atype, gboolean slowpath)
                case ATYPE_NORMAL:
                case ATYPE_SMALL:
                        mono_mb_emit_ldarg (mb, 0);
-                       mono_mb_emit_icall (mb, mono_object_new_specific);
+                       mono_mb_emit_icall (mb, ves_icall_object_new_specific);
                        break;
                case ATYPE_VECTOR:
                        mono_mb_emit_ldarg (mb, 0);
                        mono_mb_emit_ldarg (mb, 1);
-                       mono_mb_emit_icall (mb, mono_array_new_specific);
+                       mono_mb_emit_icall (mb, ves_icall_array_new_specific);
                        break;
                case ATYPE_STRING:
                        mono_mb_emit_ldarg (mb, 1);
-                       mono_mb_emit_icall (mb, mono_string_alloc);
+                       mono_mb_emit_icall (mb, ves_icall_string_alloc);
                        break;
                default:
                        g_assert_not_reached ();
@@ -1162,7 +1172,7 @@ create_allocator (int atype, gboolean slowpath)
 
                mono_mb_patch_short_branch (mb, pos);
 
-               clause = mono_image_alloc0 (mono_defaults.corlib, sizeof (MonoExceptionClause));
+               clause = (MonoExceptionClause *)mono_image_alloc0 (mono_defaults.corlib, sizeof (MonoExceptionClause));
                clause->try_offset = mono_mb_get_label (mb);
 
                /* vtable->klass->sizes.element_size */
@@ -1179,7 +1189,7 @@ create_allocator (int atype, gboolean slowpath)
                mono_mb_emit_ldarg (mb, 1);
                mono_mb_emit_byte (mb, CEE_MUL_OVF_UN);
                /* + sizeof (MonoArray) */
-               mono_mb_emit_icon (mb, sizeof (MonoArray));
+               mono_mb_emit_icon (mb, MONO_SIZEOF_MONO_ARRAY);
                mono_mb_emit_byte (mb, CEE_ADD_OVF_UN);
                mono_mb_emit_stloc (mb, size_var);
 
@@ -1188,14 +1198,12 @@ create_allocator (int atype, gboolean slowpath)
                /* catch */
                clause->flags = MONO_EXCEPTION_CLAUSE_NONE;
                clause->try_len = mono_mb_get_pos (mb) - clause->try_offset;
-               clause->data.catch_class = mono_class_from_name (mono_defaults.corlib,
+               clause->data.catch_class = mono_class_load_from_name (mono_defaults.corlib,
                                "System", "OverflowException");
-               g_assert (clause->data.catch_class);
                clause->handler_offset = mono_mb_get_label (mb);
 
-               oom_exc_class = mono_class_from_name (mono_defaults.corlib,
+               oom_exc_class = mono_class_load_from_name (mono_defaults.corlib,
                                "System", "OutOfMemoryException");
-               g_assert (oom_exc_class);
                ctor = mono_class_get_method_from_name (oom_exc_class, ".ctor", 0);
                g_assert (ctor);
 
@@ -1376,16 +1384,17 @@ create_allocator (int atype, gboolean slowpath)
        mono_mb_emit_byte (mb, CEE_RET);
 #endif
 
-       res = mono_mb_create_method (mb, csig, 8);
-       mono_mb_free (mb);
+       info = mono_wrapper_info_create (mb, WRAPPER_SUBTYPE_NONE);
+       info->d.alloc.gc_name = "sgen";
+       info->d.alloc.alloc_type = atype;
+
 #ifndef DISABLE_JIT
-       mono_method_get_header (res)->init_locals = FALSE;
+       mb->init_locals = FALSE;
 #endif
 
-       info = mono_image_alloc0 (mono_defaults.corlib, sizeof (AllocatorWrapperInfo));
-       info->gc_name = "sgen";
-       info->alloc_type = atype;
-       mono_marshal_set_wrapper_info (res, info);
+       res = mono_mb_create (mb, csig, 8, info);
+       mono_mb_free (mb);
+
 
        return res;
 }
@@ -1394,10 +1403,7 @@ create_allocator (int atype, gboolean slowpath)
 int
 mono_gc_get_aligned_size_for_allocator (int size)
 {
-       int aligned_size = size;
-       aligned_size += SGEN_ALLOC_ALIGN - 1;
-       aligned_size &= ~(SGEN_ALLOC_ALIGN - 1);
-       return aligned_size;
+       return SGEN_ALIGN_UP (size);
 }
 
 /*
@@ -1596,7 +1602,7 @@ sgen_client_cardtable_scan_object (GCObject *obj, mword block_obj_size, guint8 *
                MonoArray *arr = (MonoArray*)obj;
                guint8 *card_data, *card_base;
                guint8 *card_data_end;
-               char *obj_start = sgen_card_table_align_pointer (obj);
+               char *obj_start = (char *)sgen_card_table_align_pointer (obj);
                mword bounds_size;
                mword obj_size = sgen_mono_array_size (vt, arr, &bounds_size, sgen_vtable_get_descriptor (vt));
                /* We don't want to scan the bounds entries at the end of multidimensional arrays */
@@ -1669,13 +1675,14 @@ LOOP_HEAD:
 
                                HEAVY_STAT (++los_array_cards);
                                for (; elem < card_end; elem += SIZEOF_VOID_P) {
-                                       gpointer new, old = *(gpointer*)elem;
+                                       GCObject *new_;
+                                       gpointer old = *(gpointer*)elem;
                                        if ((mod_union && old) || G_UNLIKELY (sgen_ptr_in_nursery (old))) {
                                                HEAVY_STAT (++los_array_remsets);
                                                copy_func ((GCObject**)elem, ctx.queue);
-                                               new = *(gpointer*)elem;
-                                               if (G_UNLIKELY (sgen_ptr_in_nursery (new)))
-                                                       sgen_add_to_global_remset (elem, new);
+                                               new_ = *(GCObject **)elem;
+                                               if (G_UNLIKELY (sgen_ptr_in_nursery (new_)))
+                                                       sgen_add_to_global_remset (elem, new_);
                                        }
                                }
                        }
@@ -1728,7 +1735,7 @@ mono_gc_alloc_vector (MonoVTable *vtable, size_t size, uintptr_t max_length)
        arr = (MonoArray*)sgen_alloc_obj_nolock (vtable, size);
        if (G_UNLIKELY (!arr)) {
                UNLOCK_GC;
-               return mono_gc_out_of_memory (size);
+               return NULL;
        }
 
        arr->max_length = (mono_array_size_t)max_length;
@@ -1773,7 +1780,7 @@ mono_gc_alloc_array (MonoVTable *vtable, size_t size, uintptr_t max_length, uint
        arr = (MonoArray*)sgen_alloc_obj_nolock (vtable, size);
        if (G_UNLIKELY (!arr)) {
                UNLOCK_GC;
-               return mono_gc_out_of_memory (size);
+               return NULL;
        }
 
        arr->max_length = (mono_array_size_t)max_length;
@@ -1817,7 +1824,7 @@ mono_gc_alloc_string (MonoVTable *vtable, size_t size, gint32 len)
        str = (MonoString*)sgen_alloc_obj_nolock (vtable, size);
        if (G_UNLIKELY (!str)) {
                UNLOCK_GC;
-               return mono_gc_out_of_memory (size);
+               return NULL;
        }
 
        str->length = len;
@@ -1945,7 +1952,7 @@ precisely_report_roots_from (GCRootReport *report, void** start_root, void** end
                }
                return;
        case ROOT_DESC_COMPLEX: {
-               gsize *bitmap_data = sgen_get_complex_descriptor_bitmap (desc);
+               gsize *bitmap_data = (gsize *)sgen_get_complex_descriptor_bitmap (desc);
                gsize bwords = (*bitmap_data) - 1;
                void **start_run = start_root;
                bitmap_data++;
@@ -1983,7 +1990,7 @@ report_registered_roots_by_type (int root_type)
        void **start_root;
        RootRecord *root;
        report.count = 0;
-       SGEN_HASH_TABLE_FOREACH (&roots_hash [root_type], start_root, root) {
+       SGEN_HASH_TABLE_FOREACH (&roots_hash [root_type], void **, start_root, RootRecord *, root) {
                SGEN_LOG (6, "Precise root scan %p-%p (desc: %p)", start_root, root->end_root, (void*)root->root_desc);
                precisely_report_roots_from (&report, start_root, (void**)root->end_root, root->root_desc);
        } SGEN_HASH_TABLE_FOREACH_END;
@@ -2106,7 +2113,7 @@ collect_references (HeapWalkInfo *hwi, GCObject *obj, size_t size)
 static void
 walk_references (GCObject *start, size_t size, void *data)
 {
-       HeapWalkInfo *hwi = data;
+       HeapWalkInfo *hwi = (HeapWalkInfo *)data;
        hwi->called = 0;
        hwi->count = 0;
        collect_references (hwi, start, size);
@@ -2269,6 +2276,8 @@ thread_in_critical_region (SgenThreadInfo *info)
 static void
 sgen_thread_attach (SgenThreadInfo *info)
 {
+       mono_handle_arena_init ((MonoHandleArena**) &info->client_info.info.handle_arena);
+
        if (mono_gc_get_gc_callbacks ()->thread_attach_func && !info->client_info.runtime_data)
                info->client_info.runtime_data = mono_gc_get_gc_callbacks ()->thread_attach_func ();
 }
@@ -2284,6 +2293,8 @@ sgen_thread_detach (SgenThreadInfo *p)
         */
        if (mono_domain_get ())
                mono_thread_detach_internal (mono_thread_internal_current ());
+
+       mono_handle_arena_cleanup ((MonoHandleArena**) &p->client_info.info.handle_arena);
 }
 
 gboolean
@@ -2314,13 +2325,13 @@ static void *scan_area_arg_start, *scan_area_arg_end;
 void
 mono_gc_conservatively_scan_area (void *start, void *end)
 {
-       sgen_conservatively_pin_objects_from (start, end, scan_area_arg_start, scan_area_arg_end, PIN_TYPE_STACK);
+       sgen_conservatively_pin_objects_from ((void **)start, (void **)end, scan_area_arg_start, scan_area_arg_end, PIN_TYPE_STACK);
 }
 
 void*
 mono_gc_scan_object (void *obj, void *gc_data)
 {
-       ScanCopyContext *ctx = gc_data;
+       ScanCopyContext *ctx = (ScanCopyContext *)gc_data;
        ctx->ops->copy_or_mark_object ((GCObject**)&obj, ctx->queue);
        return obj;
 }
@@ -2331,8 +2342,6 @@ mono_gc_scan_object (void *obj, void *gc_data)
 void
 sgen_client_scan_thread_data (void *start_nursery, void *end_nursery, gboolean precise, ScanCopyContext ctx)
 {
-       SgenThreadInfo *info;
-
        scan_area_arg_start = start_nursery;
        scan_area_arg_end = end_nursery;
 
@@ -2359,25 +2368,34 @@ sgen_client_scan_thread_data (void *start_nursery, void *end_nursery, gboolean p
                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, aligned_stack_start, info->client_info.stack_end, precise, &ctx);
+                       mono_gc_get_gc_callbacks ()->thread_mark_func (info->client_info.runtime_data, (guint8 *)aligned_stack_start, (guint8 *)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 (aligned_stack_start, info->client_info.stack_end, start_nursery, end_nursery, PIN_TYPE_STACK);
+                       sgen_conservatively_pin_objects_from ((void **)aligned_stack_start, (void **)info->client_info.stack_end, start_nursery, end_nursery, PIN_TYPE_STACK);
                }
 
                if (!precise) {
 #ifdef USE_MONO_CTX
-                       sgen_conservatively_pin_objects_from ((void**)&info->client_info.ctx, (void**)&info->client_info.ctx + ARCH_NUM_REGS,
+                       sgen_conservatively_pin_objects_from ((void**)&info->client_info.ctx, (void**)(&info->client_info.ctx + 1),
                                start_nursery, end_nursery, PIN_TYPE_STACK);
 #else
                        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 = &info->client_info.info.thread_saved_state [SELF_SUSPEND_STATE_INDEX];
+                               if (state && state->gc_stackdata) {
+                                       sgen_conservatively_pin_objects_from ((void **)state->gc_stackdata, (void**)((char*)state->gc_stackdata + state->gc_stackdata_size),
+                                               start_nursery, end_nursery, PIN_TYPE_STACK);
+                               }
+                       }
                }
-       } END_FOREACH_THREAD
+       } FOREACH_THREAD_END
 }
 
 /*
@@ -2584,12 +2602,12 @@ sgen_client_metadata_for_object (GCObject *obj)
  * @gchandle: a GCHandle's handle.
  * @domain: An application domain.
  *
- * Returns: true if the object wrapped by the @gchandle belongs to the specific @domain.
+ * Returns: TRUE if the object wrapped by the @gchandle belongs to the specific @domain.
  */
 gboolean
 mono_gchandle_is_in_domain (guint32 gchandle, MonoDomain *domain)
 {
-       MonoDomain *gchandle_domain = sgen_gchandle_get_metadata (gchandle);
+       MonoDomain *gchandle_domain = (MonoDomain *)sgen_gchandle_get_metadata (gchandle);
        return domain->domain_id == gchandle_domain->domain_id;
 }
 
@@ -2608,14 +2626,14 @@ mono_gchandle_free_domain (MonoDomain *unloading)
 static gpointer
 null_link_if_in_domain (gpointer hidden, GCHandleType handle_type, int max_generation, gpointer user)
 {
-       MonoDomain *unloading_domain = user;
+       MonoDomain *unloading_domain = (MonoDomain *)user;
        MonoDomain *obj_domain;
        gboolean is_weak = MONO_GC_HANDLE_TYPE_IS_WEAK (handle_type);
        if (MONO_GC_HANDLE_IS_OBJECT_POINTER (hidden)) {
-               MonoObject *obj = MONO_GC_REVEAL_POINTER (hidden, is_weak);
+               MonoObject *obj = (MonoObject *)MONO_GC_REVEAL_POINTER (hidden, is_weak);
                obj_domain = mono_object_domain (obj);
        } else {
-               obj_domain = MONO_GC_REVEAL_POINTER (hidden, is_weak);
+               obj_domain = (MonoDomain *)MONO_GC_REVEAL_POINTER (hidden, is_weak);
        }
        if (unloading_domain->domain_id == obj_domain->domain_id)
                return NULL;
@@ -2627,7 +2645,7 @@ sgen_null_links_for_domain (MonoDomain *domain)
 {
        guint type;
        for (type = HANDLE_TYPE_MIN; type < HANDLE_TYPE_MAX; ++type)
-               sgen_gchandle_iterate (type, GENERATION_OLD, null_link_if_in_domain, domain);
+               sgen_gchandle_iterate ((GCHandleType)type, GENERATION_OLD, null_link_if_in_domain, domain);
 }
 
 void
@@ -2672,12 +2690,6 @@ sgen_client_ensure_weak_gchandles_accessible (void)
                mono_gc_wait_for_bridge_processing ();
 }
 
-gboolean
-mono_gc_set_allow_synchronous_major (gboolean flag)
-{
-       return sgen_set_allow_synchronous_major (flag);
-}
-
 void*
 mono_gc_invoke_with_gc_lock (MonoGCLockedCallbackFunc func, void *data)
 {
@@ -2694,12 +2706,6 @@ mono_gc_register_altstack (gpointer stack, gint32 stack_size, gpointer altstack,
        // FIXME:
 }
 
-void
-sgen_client_out_of_memory (size_t size)
-{
-       mono_gc_out_of_memory (size);
-}
-
 guint8*
 mono_gc_get_card_table (int *shift_bits, gpointer *mask)
 {
@@ -2729,7 +2735,7 @@ sgen_client_degraded_allocation (size_t size)
        static int last_major_gc_warned = -1;
        static int num_degraded = 0;
 
-       if (last_major_gc_warned < gc_stats.major_gc_count) {
+       if (last_major_gc_warned < (int)gc_stats.major_gc_count) {
                ++num_degraded;
                if (num_degraded == 1 || num_degraded == 3)
                        mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_GC, "Warning: Degraded allocation.  Consider increasing nursery-size if the warning persists.");
@@ -2825,7 +2831,7 @@ sgen_client_init (void)
        cb.thread_detach = sgen_thread_detach;
        cb.thread_unregister = sgen_thread_unregister;
        cb.thread_attach = sgen_thread_attach;
-       cb.mono_method_is_critical = (gpointer)is_critical_method;
+       cb.mono_method_is_critical = (gboolean (*)(void *))is_critical_method;
        cb.mono_thread_in_critical_region = thread_in_critical_region;
 
        mono_threads_init (&cb, sizeof (SgenThreadInfo));
@@ -2902,7 +2908,11 @@ sgen_client_handle_gc_debug (const char *opt)
        if (!strcmp (opt, "xdomain-checks")) {
                sgen_mono_xdomain_checks = TRUE;
        } else if (!strcmp (opt, "do-not-finalize")) {
-               do_not_finalize = TRUE;
+               mono_do_not_finalize = TRUE;
+       } else if (g_str_has_prefix (opt, "do-not-finalize=")) {
+               opt = strchr (opt, '=') + 1;
+               mono_do_not_finalize = TRUE;
+               mono_do_not_finalize_class_names = g_strsplit (opt, ",", 0);
        } else if (!strcmp (opt, "log-finalizers")) {
                log_finalizers = TRUE;
        } else if (!strcmp (opt, "no-managed-allocator")) {
@@ -2966,6 +2976,12 @@ mono_gc_base_init (void)
 
        if (nursery_canaries_enabled ())
                sgen_set_use_managed_allocator (FALSE);
+
+#if defined(HAVE_KW_THREAD)
+       /* This can happen with using libmonosgen.so */
+       if (mono_tls_key_get_offset (TLS_KEY_SGEN_TLAB_NEXT_ADDR) == -1)
+               sgen_set_use_managed_allocator (FALSE);
+#endif
 }
 
 void