Skip to content
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*
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