Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mono][gc] Remove reliance on regs/stack scanning in some cases #101478

Merged
merged 3 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/libraries/tests.proj
Original file line number Diff line number Diff line change
Expand Up @@ -395,8 +395,6 @@
<!-- Issue: https://github.com/dotnet/runtime/issues/95795 -->
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Runtime\tests\System.Globalization.Tests\Hybrid\System.Globalization.Hybrid.WASM.Tests.csproj" />
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Runtime\tests\System.Globalization.Calendars.Tests\Hybrid\System.Globalization.Calendars.Hybrid.WASM.Tests.csproj" />
<!-- Issue: https://github.com/dotnet/runtime/issues/100932 -->
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Runtime\tests\System.Reflection.Tests\System.Reflection.Tests.csproj" />
</ItemGroup>

<!-- Aggressive Trimming related failures -->
Expand Down
68 changes: 43 additions & 25 deletions src/mono/mono/metadata/reflection.c
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,48 @@ mono_type_get_object (MonoDomain *domain, MonoType *type)
return ret;
}

/* LOCKING: assumes the loader lock is taken */
static MonoReflectionType*
lambdageek marked this conversation as resolved.
Show resolved Hide resolved
mono_type_get_object_checked_alloc_helper (MonoType *type, MonoMemoryManager *memory_manager, MonoDomain *domain, MonoError *error)
{
HANDLE_FUNCTION_ENTER ();

MonoReflectionType *res, *cached;
/* This is stored in vtables/JITted code so it has to be pinned */
MonoReflectionTypeHandle res_handle = MONO_HANDLE_CAST (MonoReflectionType, mono_object_new_pinned_handle (mono_defaults.runtimetype_class, error));
goto_if_nok (error, exit);

res = MONO_HANDLE_RAW (res_handle);

res->type = type;
if (memory_manager->collectible) {
MonoObject *loader_alloc = mono_gchandle_get_target_internal (mono_mem_manager_get_loader_alloc (memory_manager));
g_assert (loader_alloc);
MONO_OBJECT_SETREF_INTERNAL (res, m_keepalive, loader_alloc);
}

mono_mem_manager_lock (memory_manager);
if (memory_manager->collectible)
cached = (MonoReflectionType *)mono_weak_hash_table_lookup (memory_manager->weak_type_hash, type);
else
cached = (MonoReflectionType *)mono_g_hash_table_lookup (memory_manager->type_hash, type);
if (cached) {
res = cached;
MONO_HANDLE_ASSIGN_RAW (res_handle, res);
} else {
if (memory_manager->collectible)
mono_weak_hash_table_insert (memory_manager->weak_type_hash, type, res);
else
mono_g_hash_table_insert_internal (memory_manager->type_hash, type, res);
if (type->type == MONO_TYPE_VOID && !m_type_is_byref (type))
domain->typeof_void = (MonoObject*)res;
}
mono_mem_manager_unlock (memory_manager);

exit:
HANDLE_FUNCTION_RETURN_OBJ (res_handle);
}

MonoReflectionType*
mono_type_get_object_checked (MonoType *type, MonoError *error)
{
Expand Down Expand Up @@ -554,33 +596,9 @@ mono_type_get_object_checked (MonoType *type, MonoError *error)
res = &mono_class_get_ref_info_raw (klass)->type; /* FIXME use handles */
goto leave;
}
/* This is stored in vtables/JITted code so it has to be pinned */
res = (MonoReflectionType *)mono_object_new_pinned (mono_defaults.runtimetype_class, error);
goto_if_nok (error, leave);

res->type = type;
if (memory_manager->collectible) {
MonoObject *loader_alloc = mono_gchandle_get_target_internal (mono_mem_manager_get_loader_alloc (memory_manager));
g_assert (loader_alloc);
MONO_OBJECT_SETREF_INTERNAL (res, m_keepalive, loader_alloc);
}

mono_mem_manager_lock (memory_manager);
if (memory_manager->collectible)
cached = (MonoReflectionType *)mono_weak_hash_table_lookup (memory_manager->weak_type_hash, type);
else
cached = (MonoReflectionType *)mono_g_hash_table_lookup (memory_manager->type_hash, type);
if (cached) {
res = cached;
} else {
if (memory_manager->collectible)
mono_weak_hash_table_insert (memory_manager->weak_type_hash, type, res);
else
mono_g_hash_table_insert_internal (memory_manager->type_hash, type, res);
if (type->type == MONO_TYPE_VOID && !m_type_is_byref (type))
domain->typeof_void = (MonoObject*)res;
}
mono_mem_manager_unlock (memory_manager);
res = mono_type_get_object_checked_alloc_helper (type, memory_manager, domain, error);

leave:
mono_loader_unlock ();
Expand Down
16 changes: 15 additions & 1 deletion src/mono/mono/sgen/sgen-gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2848,6 +2848,9 @@ sgen_gc_invoke_finalizers (void)

g_assert (!pending_unqueued_finalizer);

gboolean gchandle_allocated = FALSE;
guint32 gchandle = 0;

/* FIXME: batch to reduce lock contention */
while (sgen_have_pending_finalizers ()) {
GCObject *obj;
Expand Down Expand Up @@ -2878,8 +2881,16 @@ sgen_gc_invoke_finalizers (void)
if (!obj)
break;

// We explicitly pin the object via a gchandle so we don't rely on the ref being
// present on stack/regs which is not scannable on WASM.
if (!gchandle_allocated) {
gchandle = sgen_gchandle_new (obj, TRUE);
gchandle_allocated = TRUE;
} else {
sgen_gchandle_set_target (gchandle, obj);
}

count++;
/* the object is on the stack so it is pinned */
/*g_print ("Calling finalizer for object: %p (%s)\n", obj, sgen_client_object_safe_name (obj));*/
sgen_client_run_finalize (obj);
}
Expand All @@ -2889,6 +2900,9 @@ sgen_gc_invoke_finalizers (void)
pending_unqueued_finalizer = FALSE;
}

if (gchandle_allocated)
sgen_gchandle_free (gchandle);

return count;
}

Expand Down