From 25be848b0ec2cceda77811edc915b86c0b83aacd Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Tue, 4 Apr 2023 18:07:50 +0300 Subject: [PATCH] [mono][sgen] Remove old code associated with domain unload (#84242) * [mono][sgen] Remove unused suspend finalizers functionality * [mono][sgen] Remove threadpool shutdown logic No longer used * [mono][sgen] Remove logic associated with gc shutdown * [mono][sgen] Remove logic for clearing handle stack during cleanup * [mono][sgen] Remove code for xdomain checks * [mono][sgen] Remove more code associated with finalization * [mono][sgen] Remove code for freeing objects during domain unload * [mono][sgen] Remove mono_gc_clear_domain It is dead code --- src/mono/mono/metadata/boehm-gc.c | 16 -- src/mono/mono/metadata/gc-internals.h | 5 - src/mono/mono/metadata/handle.c | 30 --- src/mono/mono/metadata/handle.h | 1 - src/mono/mono/metadata/monitor.c | 14 -- src/mono/mono/metadata/monitor.h | 3 - src/mono/mono/metadata/sgen-client-mono.h | 23 -- src/mono/mono/metadata/sgen-mono.c | 273 +--------------------- src/mono/mono/sgen/sgen-client.h | 6 - src/mono/mono/sgen/sgen-conf.h | 8 - src/mono/mono/sgen/sgen-debug.c | 171 -------------- src/mono/mono/sgen/sgen-fin-weak-hash.c | 38 +-- src/mono/mono/sgen/sgen-gc.c | 15 -- src/mono/mono/sgen/sgen-gc.h | 8 +- src/mono/mono/sgen/sgen-marksweep.c | 50 ---- src/mono/mono/sgen/sgen-thread-pool.c | 48 +--- src/mono/mono/sgen/sgen-thread-pool.h | 2 - 17 files changed, 15 insertions(+), 696 deletions(-) diff --git a/src/mono/mono/metadata/boehm-gc.c b/src/mono/mono/metadata/boehm-gc.c index 47806e00804..803f0693f7e 100644 --- a/src/mono/mono/metadata/boehm-gc.c +++ b/src/mono/mono/metadata/boehm-gc.c @@ -205,12 +205,6 @@ mono_gc_base_init (void) gc_initialized = TRUE; } -void -mono_gc_base_cleanup (void) -{ - GC_set_finalizer_notifier (NULL); -} - void mono_gc_init_icalls (void) { @@ -893,16 +887,6 @@ mono_gc_wbarrier_object_copy_internal (MonoObject* obj, MonoObject *src) m_class_get_instance_size (mono_object_class (obj)) - MONO_ABI_SIZEOF (MonoObject)); } -void -mono_gc_clear_domain (MonoDomain *domain) -{ -} - -void -mono_gc_suspend_finalizers (void) -{ -} - int mono_gc_get_suspend_signal (void) { diff --git a/src/mono/mono/metadata/gc-internals.h b/src/mono/mono/metadata/gc-internals.h index 01aaccf710e..f0141675b27 100644 --- a/src/mono/mono/metadata/gc-internals.h +++ b/src/mono/mono/metadata/gc-internals.h @@ -69,7 +69,6 @@ mono_object_register_finalizer_handle (MonoObjectHandle obj); extern void mono_gc_init (void); MONO_COMPONENT_API extern void mono_gc_base_init (void); -extern void mono_gc_base_cleanup (void); extern void mono_gc_init_icalls (void); /* @@ -176,10 +175,6 @@ MONO_API int mono_gc_register_root (char *start, size_t size, MonoGCDescriptor MONO_COMPONENT_API void mono_gc_deregister_root (char* addr); void mono_gc_finalize_domain (MonoDomain *domain); void mono_gc_run_finalize (void *obj, void *data); -void mono_gc_clear_domain (MonoDomain * domain); -/* Signal early termination of finalizer processing inside the gc */ -void mono_gc_suspend_finalizers (void); - /* * Register a root which can only be written using a write barrier. diff --git a/src/mono/mono/metadata/handle.c b/src/mono/mono/metadata/handle.c index 09a0666ef22..8ba7e5a7cde 100644 --- a/src/mono/mono/metadata/handle.c +++ b/src/mono/mono/metadata/handle.c @@ -246,36 +246,6 @@ mono_handle_stack_free (HandleStack *stack) free_handle_stack (stack); } -void -mono_handle_stack_free_domain (HandleStack *stack, MonoDomain *domain) -{ - /* Called by the GC while clearing out objects of the given domain from the heap. */ - /* If there are no handles-related bugs, there is nothing to do: if a - * thread accessed objects from the domain it was aborted, so any - * threads left alive cannot have any handles that point into the - * unloading domain. However if there is a handle leak, the handle stack is not */ - if (!stack) - return; - /* Root domain only unloaded when mono is shutting down, don't need to check anything */ - if (domain == mono_get_root_domain () || mono_runtime_is_shutting_down ()) - return; - HandleChunk *cur = stack->bottom; - HandleChunk *last = stack->top; - if (!cur) - return; - while (cur) { - for (int idx = 0; idx < cur->size; ++idx) { - HandleChunkElem *elem = &cur->elems[idx]; - if (!elem->o) - continue; - g_assert (mono_object_domain (elem->o) != domain); - } - if (cur == last) - break; - cur = cur->next; - } -} - static void check_handle_stack_monotonic (HandleStack *stack) { diff --git a/src/mono/mono/metadata/handle.h b/src/mono/mono/metadata/handle.h index 2d9b709be1d..3b6809cfce9 100644 --- a/src/mono/mono/metadata/handle.h +++ b/src/mono/mono/metadata/handle.h @@ -135,7 +135,6 @@ HandleStack* mono_handle_stack_alloc (void); void mono_handle_stack_free (HandleStack *handlestack); MonoRawHandle mono_stack_mark_pop_value (MonoThreadInfo *info, HandleStackMark *stackmark, MonoRawHandle value); MONO_COMPONENT_API MonoThreadInfo* mono_stack_mark_record_size (MonoThreadInfo *info, HandleStackMark *stackmark, const char *func_name); -void mono_handle_stack_free_domain (HandleStack *stack, MonoDomain *domain); #ifdef MONO_HANDLE_TRACK_SP void mono_handle_chunk_leak_check (HandleStack *handles); diff --git a/src/mono/mono/metadata/monitor.c b/src/mono/mono/metadata/monitor.c index 13499b0de8b..1e861f8dec1 100644 --- a/src/mono/mono/metadata/monitor.c +++ b/src/mono/mono/metadata/monitor.c @@ -1108,20 +1108,6 @@ mono_monitor_exit (MonoObject *obj) MONO_EXTERNAL_ONLY_VOID (mono_monitor_exit_internal (obj)); } -MonoGCHandle -mono_monitor_get_object_monitor_gchandle (MonoObject *object) -{ - LockWord lw; - - lw.sync = object->synchronisation; - - if (lock_word_is_inflated (lw)) { - MonoThreadsSync *mon = lock_word_get_inflated_lock (lw); - return (MonoGCHandle)mon->data; - } - return NULL; -} - /* * mono_monitor_threads_sync_member_offset: * @status_offset: returns size and offset of the "status" member diff --git a/src/mono/mono/metadata/monitor.h b/src/mono/mono/metadata/monitor.h index cc1af3a322c..f9be43d681f 100644 --- a/src/mono/mono/metadata/monitor.h +++ b/src/mono/mono/metadata/monitor.h @@ -122,9 +122,6 @@ ICALL_EXPORT guint32 mono_monitor_enter_v4_fast (MonoObject *obj, MonoBoolean *lock_taken); -MonoGCHandle -mono_monitor_get_object_monitor_gchandle (MonoObject *object); - void mono_monitor_threads_sync_members_offset (int *status_offset, int *nest_offset); #define MONO_THREADS_SYNC_MEMBER_OFFSET(o) ((o)>>8) diff --git a/src/mono/mono/metadata/sgen-client-mono.h b/src/mono/mono/metadata/sgen-client-mono.h index 5edb3f84376..8bdae1b9fec 100644 --- a/src/mono/mono/metadata/sgen-client-mono.h +++ b/src/mono/mono/metadata/sgen-client-mono.h @@ -205,28 +205,6 @@ sgen_client_update_copied_object (char *destination, GCVTable gc_vtable, void *o mono_sgen_register_moved_object (obj, destination); } -#ifdef XDOMAIN_CHECKS_IN_WBARRIER -extern gboolean sgen_mono_xdomain_checks; - -#define sgen_client_wbarrier_generic_nostore_check(ptr) do { \ - /* FIXME: ptr_in_heap must be called with the GC lock held */ \ - if (sgen_mono_xdomain_checks && *(MonoObject**)ptr && ptr_in_heap (ptr)) { \ - char *start = find_object_for_ptr (ptr); \ - MonoObject *value = *(MonoObject**)ptr; \ - LOCK_GC; \ - SGEN_ASSERT (0, start, "Write barrier outside an object?"); \ - if (start) { \ - MonoObject *obj = (MonoObject*)start; \ - if (obj->vtable->domain != value->vtable->domain) \ - SGEN_ASSERT (0, is_xdomain_ref_allowed (ptr, start, obj->vtable->domain), "Cross-domain ref not allowed"); \ - } \ - UNLOCK_GC; \ - } \ - } while (0) -#else -#define sgen_client_wbarrier_generic_nostore_check(ptr) -#endif - static gboolean G_GNUC_UNUSED sgen_client_object_has_critical_finalizer (GCObject *obj) { @@ -738,7 +716,6 @@ gboolean sgen_is_managed_allocator (MonoMethod *method); gboolean sgen_has_managed_allocator (void); void sgen_disable_native_stack_scan (void); -void sgen_scan_for_registered_roots_in_domain (MonoDomain *domain, int root_type); void sgen_null_links_for_domain (MonoDomain *domain); #endif diff --git a/src/mono/mono/metadata/sgen-mono.c b/src/mono/mono/metadata/sgen-mono.c index 486357a5771..d23f4f57ab0 100644 --- a/src/mono/mono/metadata/sgen-mono.c +++ b/src/mono/mono/metadata/sgen-mono.c @@ -55,8 +55,6 @@ static guint64 los_array_remsets; /* If set, mark stacks conservatively, even if precise marking is possible */ static gboolean conservative_stack_mark = FALSE; -/* If set, check that there are no references to the domain left at domain unload */ -gboolean sgen_mono_xdomain_checks = FALSE; /* Functions supplied by the runtime to be called by the GC */ static MonoGCCallbacks gc_callbacks; @@ -509,17 +507,6 @@ mono_gc_register_for_finalization (MonoObject *obj, MonoFinalizationProc user_da sgen_object_register_for_finalization (obj, user_data); } -static gboolean -object_in_domain_predicate (MonoObject *obj, void *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; - } - return FALSE; -} - /** * mono_gc_finalizers_for_domain: * \param domain the unloading appdomain @@ -531,13 +518,7 @@ object_in_domain_predicate (MonoObject *obj, void *user_data) void mono_gc_finalize_domain (MonoDomain *domain) { - sgen_finalize_if (object_in_domain_predicate, domain); -} - -void -mono_gc_suspend_finalizers (void) -{ - sgen_set_suspend_finalizers (); + sgen_finalize_all (); } /* @@ -558,35 +539,6 @@ typedef struct { static EphemeronLinkNode *ephemeron_list; -/* LOCKING: requires that the GC lock is held */ -static MONO_PERMIT (need (sgen_gc_locked)) void -null_ephemerons_for_domain (MonoDomain *domain) -{ - EphemeronLinkNode *current = ephemeron_list, *prev = NULL; - - while (current) { - MonoObject *object = (MonoObject*)current->array; - - if (object) - SGEN_ASSERT (0, object->vtable, "Can't have objects without vtables."); - - if (object && object->vtable->domain == domain) { - EphemeronLinkNode *tmp = current; - - if (prev) - prev->next = current->next; - else - ephemeron_list = current->next; - - current = current->next; - sgen_free_internal (tmp, INTERNAL_MEM_EPHEMERON_LINK); - } else { - prev = current; - current = current->next; - } - } -} - /* LOCKING: requires that the GC lock is held */ void sgen_client_clear_unreachable_ephemerons (ScanCopyContext ctx) @@ -728,172 +680,6 @@ mono_gc_ephemeron_array_add (MonoObject *obj) return TRUE; } -/* - * Appdomain handling - */ - -static gboolean -need_remove_object_for_domain (GCObject *start, MonoDomain *domain) -{ - if (mono_object_domain (start) == domain) { - SGEN_LOG (4, "Need to cleanup object %p", start); - sgen_binary_protocol_cleanup (start, (gpointer)SGEN_LOAD_VTABLE (start), sgen_safe_object_get_size ((GCObject*)start)); - return TRUE; - } - return FALSE; -} - -static void -process_object_for_domain_clearing (GCObject *start, MonoDomain *domain) -{ - MonoVTable *vt = SGEN_LOAD_VTABLE (start); - if (vt->klass == mono_defaults.internal_thread_class) - g_assert (mono_object_domain (start) == mono_get_root_domain ()); -} - -static gboolean -clear_domain_process_object (GCObject *obj, MonoDomain *domain) -{ - gboolean remove; - - process_object_for_domain_clearing (obj, domain); - remove = need_remove_object_for_domain (obj, domain); - - if (remove && obj->synchronisation) { - MonoGCHandle dislink = mono_monitor_get_object_monitor_gchandle (obj); - if (dislink) - mono_gchandle_free_internal (dislink); - } - - return remove; -} - -static void -clear_domain_process_minor_object_callback (GCObject *obj, size_t size, MonoDomain *domain) -{ - if (clear_domain_process_object (obj, domain)) { - CANARIFY_SIZE (size); - memset (obj, 0, size); - } -} - -static void -clear_domain_process_major_object_callback (GCObject *obj, size_t size, MonoDomain *domain) -{ - clear_domain_process_object (obj, domain); -} - -static void -clear_domain_free_major_non_pinned_object_callback (GCObject *obj, size_t size, MonoDomain *domain) -{ - if (need_remove_object_for_domain (obj, domain)) - sgen_major_collector.free_non_pinned_object (obj, size); -} - -static void -clear_domain_free_major_pinned_object_callback (GCObject *obj, size_t size, MonoDomain *domain) -{ - if (need_remove_object_for_domain (obj, domain)) - sgen_major_collector.free_pinned_object (obj, size); -} - -static void -clear_domain_process_los_object_callback (GCObject *obj, size_t size, MonoDomain *domain) -{ - clear_domain_process_object (obj, domain); -} - -static gboolean -clear_domain_free_los_object_callback (GCObject *obj, size_t size, MonoDomain *domain) -{ - return need_remove_object_for_domain (obj, domain); -} - -static void -sgen_finish_concurrent_work (const char *reason, gboolean stw) -{ - if (sgen_get_concurrent_collection_in_progress ()) - sgen_perform_collection (0, GENERATION_OLD, reason, TRUE, stw); - SGEN_ASSERT (0, !sgen_get_concurrent_collection_in_progress (), "We just ordered a synchronous collection. Why are we collecting concurrently?"); - - sgen_major_collector.finish_sweeping (); -} - -/* - * When appdomains are unloaded we can easily remove objects that have finalizers, - * but all the others could still be present in random places on the heap. - * We need a sweep to get rid of them even though it's going to be costly - * with big heaps. - * The reason we need to remove them is because we access the vtable and class - * structures to know the object size and the reference bitmap: once the domain is - * unloaded the point to random memory. - */ -void -mono_gc_clear_domain (MonoDomain * domain) -{ - int i; - - LOCK_GC; - - sgen_binary_protocol_domain_unload_begin (domain); - - sgen_stop_world (0, FALSE); - - sgen_finish_concurrent_work ("clear domain", FALSE); - - sgen_process_fin_stage_entries (); - - sgen_clear_nursery_fragments (); - - FOREACH_THREAD_ALL (info) { - mono_handle_stack_free_domain (info->client_info.info.handle_stack, domain); - } FOREACH_THREAD_END - - if (sgen_mono_xdomain_checks && domain != mono_get_root_domain ()) { - sgen_scan_for_registered_roots_in_domain (domain, ROOT_TYPE_NORMAL); - sgen_scan_for_registered_roots_in_domain (domain, ROOT_TYPE_WBARRIER); - sgen_check_for_xdomain_refs (); - } - - /*Ephemerons and dislinks must be processed before LOS since they might end up pointing - to memory returned to the OS.*/ - null_ephemerons_for_domain (domain); - sgen_null_links_for_domain (domain); - - for (i = GENERATION_NURSERY; i < GENERATION_MAX; ++i) - sgen_remove_finalizers_if (object_in_domain_predicate, domain, i); - - sgen_scan_area_with_callback (sgen_nursery_section->data, sgen_nursery_section->end_data, - (IterateObjectCallbackFunc)clear_domain_process_minor_object_callback, domain, FALSE, TRUE); - - /* We need two passes over major and large objects because - freeing such objects might give their memory back to the OS - (in the case of large objects) or obliterate its vtable - (pinned objects with major-copying or pinned and non-pinned - objects with major-mark&sweep), but we might need to - dereference a pointer from an object to another object if - the first object is a proxy. */ - sgen_major_collector.iterate_objects (ITERATE_OBJECTS_SWEEP_ALL, (IterateObjectCallbackFunc)clear_domain_process_major_object_callback, domain); - - sgen_los_iterate_objects ((IterateObjectCallbackFunc)clear_domain_process_los_object_callback, domain); - sgen_los_iterate_objects_free ((IterateObjectResultCallbackFunc)clear_domain_free_los_object_callback, domain); - - sgen_major_collector.iterate_objects (ITERATE_OBJECTS_SWEEP_NON_PINNED, (IterateObjectCallbackFunc)clear_domain_free_major_non_pinned_object_callback, domain); - sgen_major_collector.iterate_objects (ITERATE_OBJECTS_SWEEP_PINNED, (IterateObjectCallbackFunc)clear_domain_free_major_pinned_object_callback, domain); - - if (domain == mono_get_root_domain ()) { - sgen_pin_stats_report (); - sgen_object_layout_dump (stdout); - } - - sgen_restart_world (0, FALSE); - - sgen_binary_protocol_domain_unload_end (domain); - sgen_binary_protocol_flush_buffers (FALSE); - - UNLOCK_GC; -} - /* * Allocation */ @@ -2770,31 +2556,6 @@ mono_gchandle_get_target_internal (MonoGCHandle gchandle) return sgen_gchandle_get_target (MONO_GC_HANDLE_TO_UINT (gchandle)); } -static gpointer -null_link_if_in_domain (gpointer hidden, GCHandleType handle_type, int max_generation, gpointer 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 = (MonoObject *)MONO_GC_REVEAL_POINTER (hidden, is_weak); - obj_domain = mono_object_domain (obj); - } else { - obj_domain = (MonoDomain *)MONO_GC_REVEAL_POINTER (hidden, is_weak); - } - if (unloading_domain->domain_id == obj_domain->domain_id) - return NULL; - return hidden; -} - -void -sgen_null_links_for_domain (MonoDomain *domain) -{ - guint type; - for (type = HANDLE_TYPE_MIN; type < HANDLE_TYPE_MAX; ++type) - sgen_gchandle_iterate ((GCHandleType)type, GENERATION_OLD, null_link_if_in_domain, domain); -} - void mono_gchandle_set_target (MonoGCHandle gchandle, MonoObject *obj) { @@ -2919,15 +2680,6 @@ sgen_client_description_for_internal_mem_type (int type) } } -void -sgen_client_pre_collection_checks (void) -{ - if (sgen_mono_xdomain_checks) { - sgen_clear_nursery_fragments (); - sgen_check_for_xdomain_refs (); - } -} - gboolean sgen_client_vtable_is_inited (MonoVTable *vt) { @@ -3012,9 +2764,7 @@ sgen_client_print_gc_params_usage (void) gboolean 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")) { + if (!strcmp (opt, "do-not-finalize")) { mono_do_not_finalize = TRUE; } else if (g_str_has_prefix (opt, "do-not-finalize=")) { opt = strchr (opt, '=') + 1; @@ -3040,7 +2790,6 @@ sgen_client_handle_gc_debug (const char *opt) void sgen_client_print_gc_debug_usage (void) { - fprintf (stderr, " xdomain-checks\n"); fprintf (stderr, " do-not-finalize\n"); fprintf (stderr, " log-finalizers\n"); fprintf (stderr, " no-managed-allocator\n"); @@ -3103,24 +2852,6 @@ mono_gc_base_init (void) gc_inited = TRUE; } -void -mono_gc_base_cleanup (void) -{ - /* - * Note we don't fully cleanup the GC here, but the threads mainly. - * - * We need to finish any work on the sgen threads before shutting down - * the sgen threadpool. After this point we can still trigger GCs as - * part of domain free, but they should all be forced and not use the - * threadpool. - */ - sgen_finish_concurrent_work ("cleanup", TRUE); - sgen_thread_pool_shutdown (); - - // We should have consumed any outstanding moves. - g_assert (sgen_pointer_queue_is_empty (&moved_objects_queue)); -} - gboolean mono_gc_is_null (void) { diff --git a/src/mono/mono/sgen/sgen-client.h b/src/mono/mono/sgen/sgen-client.h index d4dfb4a3984..6ecfa09b314 100644 --- a/src/mono/mono/sgen/sgen-client.h +++ b/src/mono/mono/sgen/sgen-client.h @@ -162,12 +162,6 @@ gboolean sgen_client_vtable_is_inited (GCVTable vtable); const char* sgen_client_vtable_get_namespace (GCVTable vtable); const char* sgen_client_vtable_get_name (GCVTable vtable); -/* - * Called before starting collections. The world is already stopped. No action is - * necessary. - */ -void sgen_client_pre_collection_checks (void); - /* * Must set the thread's thread info to `info`. If the thread's small ID was not already * initialized in `sgen_client_init()` (for the main thread, usually), it must be done here. diff --git a/src/mono/mono/sgen/sgen-conf.h b/src/mono/mono/sgen/sgen-conf.h index b0ed17521d9..2f988b6460c 100644 --- a/src/mono/mono/sgen/sgen-conf.h +++ b/src/mono/mono/sgen/sgen-conf.h @@ -80,12 +80,6 @@ typedef target_mword SgenDescriptor; */ //#define SGEN_CHECK_UPDATE_REFERENCE -/* - * Define this and use the "xdomain-checks" MONO_GC_DEBUG option to - * have cross-domain checks in the write barrier. - */ -//#define XDOMAIN_CHECKS_IN_WBARRIER - /* * Define this to get number of objects marked information in the * concurrent GC DTrace probes. Has a small performance impact, so @@ -105,11 +99,9 @@ typedef target_mword SgenDescriptor; #ifndef SGEN_HEAVY_BINARY_PROTOCOL #ifndef HEAVY_STATISTICS #define MANAGED_ALLOCATION -#ifndef XDOMAIN_CHECKS_IN_WBARRIER #define MANAGED_WBARRIER #endif #endif -#endif #if defined (HOST_WASM) || defined(TARGET_WASM) #define DEFAULT_MAJOR SGEN_MAJOR_SERIAL diff --git a/src/mono/mono/sgen/sgen-debug.c b/src/mono/mono/sgen/sgen-debug.c index cfec7528ccb..ea2caeba2b6 100644 --- a/src/mono/mono/sgen/sgen-debug.c +++ b/src/mono/mono/sgen/sgen-debug.c @@ -860,167 +860,6 @@ mono_gc_scan_for_specific_ref (GCObject *key, gboolean precise) find_pinning_ref_from_thread ((char*)key, sizeof (GCObject)); } -#ifndef SGEN_WITHOUT_MONO - -static MonoDomain *check_domain = NULL; - -static void -check_obj_not_in_domain (MonoObject **o) -{ - g_assert (((*o))->vtable->domain != check_domain); -} - - -static void -check_obj_not_in_domain_callback (GCObject **o, void *gc_data) -{ - g_assert ((*o)->vtable->domain != check_domain); -} - -void -sgen_scan_for_registered_roots_in_domain (MonoDomain *domain, int root_type) -{ - void **start_root; - RootRecord *root; - check_domain = domain; - SGEN_HASH_TABLE_FOREACH (&sgen_roots_hash [root_type], void **, start_root, RootRecord *, root) { - SgenDescriptor desc = root->root_desc; - - /* The MonoDomain struct is allowed to hold - references to objects in its own domain. */ - if (start_root == (void**)domain) - continue; - - switch (desc & ROOT_DESC_TYPE_MASK) { - case ROOT_DESC_BITMAP: - desc >>= ROOT_DESC_TYPE_SHIFT; - while (desc) { - if ((desc & 1) && *start_root) - check_obj_not_in_domain ((MonoObject **)*start_root); - desc >>= 1; - start_root++; - } - break; - case ROOT_DESC_COMPLEX: { - gsize *bitmap_data = (gsize *)sgen_get_complex_descriptor_bitmap (desc); - int bwords = (int)((*bitmap_data) - 1); - void **start_run = start_root; - bitmap_data++; - while (bwords-- > 0) { - gsize bmap = *bitmap_data++; - void **objptr = start_run; - while (bmap) { - if ((bmap & 1) && *objptr) - check_obj_not_in_domain ((MonoObject **)*objptr); - bmap >>= 1; - ++objptr; - } - start_run += GC_BITS_PER_WORD; - } - break; - } - case ROOT_DESC_VECTOR: { - void **p; - - for (p = start_root; p < (void**)root->end_root; p++) { - if (*p) - check_obj_not_in_domain ((MonoObject **)*p); - } - break; - } - case ROOT_DESC_USER: { - SgenUserRootMarkFunc marker = sgen_get_user_descriptor_func (desc); - marker (start_root, check_obj_not_in_domain_callback, NULL); - break; - } - case ROOT_DESC_RUN_LEN: - g_assert_not_reached (); - default: - g_assert_not_reached (); - } - } SGEN_HASH_TABLE_FOREACH_END; - - check_domain = NULL; -} - -static gboolean -is_xdomain_ref_allowed (GCObject **ptr, GCObject *obj, MonoDomain *domain) -{ - return FALSE; -} - -static void -check_reference_for_xdomain (GCObject **ptr, GCObject *obj, MonoDomain *domain) -{ - MonoObject *ref = *ptr; - size_t offset = (char*)(ptr) - (char*)obj; - MonoClass *klass; - MonoClassField *field; - char *str; - - if (!ref || ref->vtable->domain == domain) - return; - if (is_xdomain_ref_allowed (ptr, obj, domain)) - return; - - field = NULL; - for (klass = obj->vtable->klass; klass; klass = m_class_get_parent (klass)) { - gpointer iter = NULL; - MonoClassField *cur; - while ((cur = mono_class_get_fields_internal (klass, &iter))) { - /* metadata-update: there are no domains in .NET */ - g_assert (!m_field_is_from_update (cur)); - if (m_field_get_offset (cur) == offset) { - field = cur; - break; - } - } - if (field) - break; - } - - if (ref->vtable->klass == mono_defaults.string_class) { - ERROR_DECL (error); - str = mono_string_to_utf8_checked_internal ((MonoString*)ref, error); - mono_error_cleanup (error); - } else - str = NULL; - g_print ("xdomain reference in %p (%s.%s) at offset %zu (%s) to %p (%s.%s) (%s) - pointed to by:\n", - obj, m_class_get_name_space (obj->vtable->klass), m_class_get_name (obj->vtable->klass), - offset, field ? field->name : "", - ref, m_class_get_name_space (ref->vtable->klass), m_class_get_name (ref->vtable->klass), str ? str : ""); - mono_gc_scan_for_specific_ref (obj, TRUE); - if (str) - g_free (str); -} - -#undef HANDLE_PTR -#define HANDLE_PTR(ptr,obj) check_reference_for_xdomain ((ptr), (obj), domain) - -static void -scan_object_for_xdomain_refs (GCObject *obj, mword size, void *data) -{ - char *start = (char*)obj; - MonoVTable *vtable = SGEN_LOAD_VTABLE (obj); - MonoDomain *domain = vtable->domain; - SgenDescriptor desc = sgen_vtable_get_descriptor (vtable); - - #include "sgen-scan-object.h" -} - -void -sgen_check_for_xdomain_refs (void) -{ - sgen_scan_area_with_callback (sgen_nursery_section->data, sgen_nursery_section->end_data, - (IterateObjectCallbackFunc)scan_object_for_xdomain_refs, NULL, FALSE, TRUE); - - sgen_major_collector.iterate_objects (ITERATE_OBJECTS_SWEEP_ALL, (IterateObjectCallbackFunc)scan_object_for_xdomain_refs, NULL); - - sgen_los_iterate_objects ((IterateObjectCallbackFunc)scan_object_for_xdomain_refs, NULL); -} - -#endif - /* If not null, dump the heap after each collection into this file */ static FILE *heap_dump_file = NULL; @@ -1209,11 +1048,6 @@ sgen_find_object_for_ptr (char *ptr) #else -void -sgen_check_for_xdomain_refs (void) -{ -} - void sgen_check_heap_marked (gboolean nursery_must_be_pinned) { @@ -1269,10 +1103,5 @@ sgen_dump_occupied (char *start, char *end, char *section_start) { } -void -sgen_scan_for_registered_roots_in_domain (MonoDomain *domain, int root_type) -{ -} - #endif /*DISABLE_SGEN_DEBUG_HELPERS */ #endif /*HAVE_SGEN_GC*/ diff --git a/src/mono/mono/sgen/sgen-fin-weak-hash.c b/src/mono/mono/sgen/sgen-fin-weak-hash.c index b523c786164..7b5f3c908ae 100644 --- a/src/mono/mono/sgen/sgen-fin-weak-hash.c +++ b/src/mono/mono/sgen/sgen-fin-weak-hash.c @@ -568,7 +568,7 @@ sgen_object_register_for_finalization (GCObject *obj, SGenFinalizationProc user_ /* LOCKING: requires that the GC lock is held */ static MONO_PERMIT (need (sgen_gc_locked)) void -finalize_with_predicate (SgenObjectPredicateFunc predicate, void *user_data, SgenHashTable *hash_table) +finalize_all (SgenHashTable *hash_table) { GCObject *object; gpointer dummy G_GNUC_UNUSED; @@ -578,15 +578,10 @@ finalize_with_predicate (SgenObjectPredicateFunc predicate, void *user_data, Sge SGEN_HASH_TABLE_FOREACH (hash_table, GCObject *, object, gpointer, dummy) { object = tagged_object_get_object (object); - if (predicate (object, user_data)) { - /* remove and put in out_array */ - SGEN_HASH_TABLE_FOREACH_REMOVE (TRUE); - sgen_queue_finalization_entry (object); - SGEN_LOG (5, "Enqueuing object for finalization: %p (%s) (%d)", object, sgen_client_vtable_get_name (SGEN_LOAD_VTABLE (object)), sgen_hash_table_num_entries (hash_table)); - } - - if (sgen_suspend_finalizers) - break; + /* remove and put in out_array */ + SGEN_HASH_TABLE_FOREACH_REMOVE (TRUE); + sgen_queue_finalization_entry (object); + SGEN_LOG (5, "Enqueuing object for finalization: %p (%s) (%d)", object, sgen_client_vtable_get_name (SGEN_LOAD_VTABLE (object)), sgen_hash_table_num_entries (hash_table)); } SGEN_HASH_TABLE_FOREACH_END; } @@ -607,32 +602,15 @@ finalize_with_predicate (SgenObjectPredicateFunc predicate, void *user_data, Sge * objects are still alive. */ void -sgen_finalize_if (SgenObjectPredicateFunc predicate, void *user_data) +sgen_finalize_all () { LOCK_GC; sgen_process_fin_stage_entries (); - finalize_with_predicate (predicate, user_data, &minor_finalizable_hash); - finalize_with_predicate (predicate, user_data, &major_finalizable_hash); + finalize_all (&minor_finalizable_hash); + finalize_all (&major_finalizable_hash); UNLOCK_GC; } -void -sgen_remove_finalizers_if (SgenObjectPredicateFunc predicate, void *user_data, int generation) -{ - SgenHashTable *hash_table = get_finalize_entry_hash_table (generation); - GCObject *object; - gpointer dummy G_GNUC_UNUSED; - - SGEN_HASH_TABLE_FOREACH (hash_table, GCObject *, object, gpointer, dummy) { - object = tagged_object_get_object (object); - - if (predicate (object, user_data)) { - SGEN_HASH_TABLE_FOREACH_REMOVE (TRUE); - continue; - } - } SGEN_HASH_TABLE_FOREACH_END; -} - void sgen_init_fin_weak_hash (void) { diff --git a/src/mono/mono/sgen/sgen-gc.c b/src/mono/mono/sgen/sgen-gc.c index 2ef4c60538c..56b6e370b74 100644 --- a/src/mono/mono/sgen/sgen-gc.c +++ b/src/mono/mono/sgen/sgen-gc.c @@ -1839,8 +1839,6 @@ collect_nursery (const char *reason, gboolean is_overflow) TV_GETTIME (btv); time_minor_pre_collection_fragment_clear += TV_ELAPSED (atv, btv); - sgen_client_pre_collection_checks (); - sgen_major_collector.start_nursery_collection (); sgen_memgov_minor_collection_start (); @@ -2078,8 +2076,6 @@ major_copy_or_mark_from_roots (SgenGrayQueue *gc_thread_gray_queue, size_t *old_ objects_pinned = 0; - sgen_client_pre_collection_checks (); - if (mode != COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT) { /* Remsets are not useful for a major collection */ remset.clear_cards (); @@ -2844,13 +2840,6 @@ sgen_object_is_live (GCObject *obj) */ static volatile gboolean pending_unqueued_finalizer = FALSE; -volatile gboolean sgen_suspend_finalizers = FALSE; - -void -sgen_set_suspend_finalizers (void) -{ - sgen_suspend_finalizers = TRUE; -} int sgen_gc_invoke_finalizers (void) @@ -2906,8 +2895,6 @@ sgen_gc_invoke_finalizers (void) gboolean sgen_have_pending_finalizers (void) { - if (sgen_suspend_finalizers) - return FALSE; return pending_unqueued_finalizer || !sgen_pointer_queue_is_empty (&fin_ready_queue) || !sgen_pointer_queue_is_empty (&critical_fin_queue); } @@ -3153,8 +3140,6 @@ mono_gc_wbarrier_generic_nostore_internal (gpointer ptr) HEAVY_STAT (++stat_wbarrier_generic_store); - sgen_client_wbarrier_generic_nostore_check (ptr); - obj = *(gpointer*)ptr; if (obj) sgen_binary_protocol_wbarrier (ptr, obj, (gpointer)LOAD_VTABLE (obj)); diff --git a/src/mono/mono/sgen/sgen-gc.h b/src/mono/mono/sgen/sgen-gc.h index 65de0d4aec9..2e59db54be1 100644 --- a/src/mono/mono/sgen/sgen-gc.h +++ b/src/mono/mono/sgen/sgen-gc.h @@ -688,7 +688,6 @@ struct _SgenMajorCollector { GCObject* (*alloc_object) (GCVTable vtable, size_t size, gboolean has_references); GCObject* (*alloc_object_par) (GCVTable vtable, size_t size, gboolean has_references); - void (*free_pinned_object) (GCObject *obj, size_t size); /* * This is used for domain unloading, heap walking from the logging profiler, and @@ -696,7 +695,6 @@ struct _SgenMajorCollector { */ void (*iterate_objects) (IterateObjectsFlags flags, IterateObjectCallbackFunc callback, void *data); - void (*free_non_pinned_object) (GCObject *obj, size_t size); void (*pin_objects) (SgenGrayQueue *queue); void (*pin_major_object) (GCObject *obj, SgenGrayQueue *queue); void (*scan_card_table) (CardTableScanType scan_type, ScanCopyContext ctx, int job_index, int job_split_count, int block_count); @@ -902,10 +900,8 @@ typedef void (*SGenFinalizationProc)(gpointer, gpointer); // same as MonoFinaliz void sgen_object_register_for_finalization (GCObject *obj, SGenFinalizationProc user_data) MONO_PERMIT (need (sgen_lock_gc)); -void sgen_finalize_if (SgenObjectPredicateFunc predicate, void *user_data) +void sgen_finalize_all (void) MONO_PERMIT (need (sgen_lock_gc)); -void sgen_remove_finalizers_if (SgenObjectPredicateFunc predicate, void *user_data, int generation); -void sgen_set_suspend_finalizers (void); void sgen_wbroots_iterate_live_block_ranges (sgen_cardtable_block_callback cb); void sgen_wbroots_scan_card_table (ScanCopyContext ctx); @@ -1106,7 +1102,6 @@ extern NurseryClearPolicy sgen_nursery_clear_policy; extern gboolean sgen_try_free_some_memory; extern mword sgen_total_promoted_size; extern mword sgen_total_allocated_major; -extern volatile gboolean sgen_suspend_finalizers; extern MonoCoopMutex sgen_gc_mutex; #ifndef DISABLE_SGEN_MAJOR_MARKSWEEP_CONC extern volatile gboolean sgen_concurrent_collection_in_progress; @@ -1160,7 +1155,6 @@ void sgen_check_whole_heap_stw (void) void sgen_check_objref (char *obj); void sgen_check_heap_marked (gboolean nursery_must_be_pinned); void sgen_check_nursery_objects_untag (void); -void sgen_check_for_xdomain_refs (void); GCObject* sgen_find_object_for_ptr (char *ptr); void mono_gc_scan_for_specific_ref (GCObject *key, gboolean precise); diff --git a/src/mono/mono/sgen/sgen-marksweep.c b/src/mono/mono/sgen/sgen-marksweep.c index 7bb27a56ca8..26529dddc11 100644 --- a/src/mono/mono/sgen/sgen-marksweep.c +++ b/src/mono/mono/sgen/sgen-marksweep.c @@ -772,48 +772,6 @@ get_block: return (GCObject *)obj; } -/* - * We're not freeing the block if it's empty. We leave that work for - * the next major collection. - * - * This is just called from the domain clearing code, which runs in a - * single thread and has the GC lock, so we don't need an extra lock. - */ -static void -free_object (GCObject *obj, size_t size, gboolean pinned) -{ - MSBlockInfo *block = MS_BLOCK_FOR_OBJ (obj); - int word, bit; - gboolean in_free_list; - - SGEN_ASSERT (9, sweep_state == SWEEP_STATE_SWEPT, "Should have waited for sweep to free objects."); - - ensure_can_access_block_free_list (block); - SGEN_ASSERT (9, (pinned && block->pinned) || (!pinned && !block->pinned), "free-object pinning mixup object %p pinned %d block %p pinned %d", obj, pinned, block, block->pinned); - SGEN_ASSERT (9, MS_OBJ_ALLOCED (obj, block), "object %p is already free", obj); - MS_CALC_MARK_BIT (word, bit, obj); - SGEN_ASSERT (9, !MS_MARK_BIT (block, word, bit), "object %p has mark bit set", obj); - - memset (obj, 0, size); - - in_free_list = !!block->free_list; - *(void**)obj = block->free_list; - block->free_list = (void**)obj; - - if (!in_free_list) { - MSBlockInfo * volatile *free_blocks = FREE_BLOCKS (pinned, block->has_references); - int size_index = MS_BLOCK_OBJ_SIZE_INDEX (size); - SGEN_ASSERT (9, !block->next_free, "block %p doesn't have a free-list of object but belongs to a free-list of blocks", block); - add_free_block (free_blocks, size_index, block); - } -} - -static void -major_free_non_pinned_object (GCObject *obj, size_t size) -{ - free_object (obj, size, FALSE); -} - /* size is a multiple of SGEN_ALLOC_ALIGN */ static GCObject* major_alloc_small_pinned_obj (GCVTable vtable, size_t size, gboolean has_references) @@ -831,12 +789,6 @@ major_alloc_small_pinned_obj (GCVTable vtable, size_t size, gboolean has_referen return (GCObject *)res; } -static void -free_pinned_object (GCObject *obj, size_t size) -{ - free_object (obj, size, TRUE); -} - /* * size is already rounded up and we hold the GC lock. */ @@ -2922,9 +2874,7 @@ sgen_marksweep_init_internal (SgenMajorCollector *collector, gboolean is_concurr #ifndef DISABLE_SGEN_MAJOR_MARKSWEEP_CONC collector->alloc_object_par = major_alloc_object_par; #endif - collector->free_pinned_object = free_pinned_object; collector->iterate_objects = major_iterate_objects; - collector->free_non_pinned_object = major_free_non_pinned_object; collector->pin_objects = major_pin_objects; collector->pin_major_object = pin_major_object; collector->scan_card_table = major_scan_card_table; diff --git a/src/mono/mono/sgen/sgen-thread-pool.c b/src/mono/mono/sgen/sgen-thread-pool.c index 512d6f14b5b..33887a7aada 100644 --- a/src/mono/mono/sgen/sgen-thread-pool.c +++ b/src/mono/mono/sgen/sgen-thread-pool.c @@ -25,9 +25,6 @@ static int threads_num; static MonoNativeThreadId threads [SGEN_THREADPOOL_MAX_NUM_THREADS]; static int threads_context [SGEN_THREADPOOL_MAX_NUM_THREADS]; -static volatile gboolean threadpool_shutdown; -static volatile int threads_finished; - static int contexts_num; static SgenThreadPoolContext pool_contexts [SGEN_THREADPOOL_MAX_NUM_CONTEXTS]; @@ -129,7 +126,7 @@ has_priority_work (int worker_index, int current_context) static void get_work (int worker_index, int *work_context, int *do_idle, SgenThreadPoolJob **job) { - while (!threadpool_shutdown) { + while (TRUE) { int i; for (i = 0; i < contexts_num; i++) { @@ -198,10 +195,8 @@ thread_func (void *data) get_work (worker_index, ¤t_context, &do_idle, &job); threads_context [worker_index] = current_context; - if (!threadpool_shutdown) { - context = &pool_contexts [current_context]; - thread_data = (context->thread_datas) ? context->thread_datas [worker_index] : NULL; - } + context = &pool_contexts [current_context]; + thread_data = (context->thread_datas) ? context->thread_datas [worker_index] : NULL; mono_os_mutex_unlock (&lock); @@ -230,12 +225,7 @@ thread_func (void *data) if (!do_idle) mono_os_cond_signal (&done_cond); } else { - SGEN_ASSERT (0, threadpool_shutdown, "Why did we unlock if no jobs and not shutting down?"); - mono_os_mutex_lock (&lock); - threads_finished++; - mono_os_cond_signal (&done_cond); - mono_os_mutex_unlock (&lock); - return 0; + g_assert_not_reached (); } } @@ -288,36 +278,11 @@ sgen_thread_pool_start (void) mono_os_cond_init (&work_cond); mono_os_cond_init (&done_cond); - threads_finished = 0; - threadpool_shutdown = FALSE; - for (i = 0; i < threads_num; i++) { mono_native_thread_create (&threads [i], (gpointer)thread_func, (void*)(gsize)i); } } -void -sgen_thread_pool_shutdown (void) -{ - if (!threads_num) - return; - - mono_os_mutex_lock (&lock); - threadpool_shutdown = TRUE; - mono_os_cond_broadcast (&work_cond); - while (threads_finished < threads_num) - mono_os_cond_wait (&done_cond, &lock); - mono_os_mutex_unlock (&lock); - - mono_os_mutex_destroy (&lock); - mono_os_cond_destroy (&work_cond); - mono_os_cond_destroy (&done_cond); - - for (int i = 0; i < threads_num; i++) { - mono_threads_add_joinable_thread ((gpointer)(gsize)threads [i]); - } -} - SgenThreadPoolJob* sgen_thread_pool_job_alloc (const char *name, SgenThreadPoolJobFunc func, size_t size) { @@ -461,11 +426,6 @@ sgen_thread_pool_start (void) { } -void -sgen_thread_pool_shutdown (void) -{ -} - SgenThreadPoolJob* sgen_thread_pool_job_alloc (const char *name, SgenThreadPoolJobFunc func, size_t size) { diff --git a/src/mono/mono/sgen/sgen-thread-pool.h b/src/mono/mono/sgen/sgen-thread-pool.h index c19f109eda6..a3fe191e71c 100644 --- a/src/mono/mono/sgen/sgen-thread-pool.h +++ b/src/mono/mono/sgen/sgen-thread-pool.h @@ -57,8 +57,6 @@ struct _SgenThreadPoolContext { int sgen_thread_pool_create_context (int num_threads, SgenThreadPoolThreadInitFunc init_func, SgenThreadPoolIdleJobFunc idle_func, SgenThreadPoolContinueIdleJobFunc continue_idle_func, SgenThreadPoolShouldWorkFunc should_work_func, void **thread_datas); void sgen_thread_pool_start (void); -void sgen_thread_pool_shutdown (void); - SgenThreadPoolJob* sgen_thread_pool_job_alloc (const char *name, SgenThreadPoolJobFunc func, size_t size); /* This only needs to be called on jobs that are not enqueued. */ void sgen_thread_pool_job_free (SgenThreadPoolJob *job); -- GitLab