Skip to content

Commit

Permalink
[mono][metadata] Allocate handle while operating with newly allocated…
Browse files Browse the repository at this point in the history
… RuntimeType
  • Loading branch information
BrzVlad committed Apr 25, 2024
1 parent c02f8cd commit 8c67b76
Showing 1 changed file with 42 additions and 25 deletions.
67 changes: 42 additions & 25 deletions src/mono/mono/metadata/reflection.c
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,47 @@ 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;
} 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 +595,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

0 comments on commit 8c67b76

Please sign in to comment.