-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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] fix two call get_default_jit_mm make hotreload work in non default alc #84247
Conversation
…XIT_GC_UNSAFE; mono_runtime_delegate_invoke wrapper with MONO_ENTER_GC_UNSAFE/MONO_EXIT_GC_UNSAFE;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR! This is definitly something we need to address, otherwise hot reload has no effect on methods in non-default ALCs.
The current PR introduces a lock order dependency between two low-level locks that I think will be fragile. It would be better if we could iterate over a copy of the ALCs list, while also having some way to prevent the individual ALCs from being collected until the iteration is done.
src/mono/mono/mini/interp/interp.c
Outdated
InterpJitInfoFuncUserData func_data; | ||
func_data.func = func; | ||
func_data.user_data = user_data; | ||
mono_alc_foreach (interp_invalidate_transformed_func, &func_data); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo? should be interp_jit_info_foreach_func
src/mono/mono/mini/interp/interp.c
Outdated
jit_mm_lock (jit_mm); | ||
mono_internal_hash_table_apply (&jit_mm->interp_code_hash, invalidate_transform, NULL); | ||
jit_mm_unlock (jit_mm); | ||
mono_alc_foreach (interp_invalidate_transformed_func, NULL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will call interp_invalidate_transformed_func
while holding the alc_list_lock
src/mono/mono/mini/interp/interp.c
Outdated
MonoAssemblyLoadContext* alc = (MonoAssemblyLoadContext*)data; | ||
MonoJitMemoryManager *jit_mm = (MonoJitMemoryManager*)(alc->memory_manager->runtime_info); | ||
|
||
jit_mm_lock (jit_mm); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When interp_invalidate_transformed_func
is called, it will take the jit memory manager lock.
So we're implicitly introducing a lock order: alcs_list_lock > MonoMemoryManager:lock
alcs_lock (); | ||
g_slist_foreach (alcs, func, user_data); | ||
alcs_unlock (); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like that this creates a lock ordering dependency between the jit memory manager locks and the alcs lock. It's not particularly obvious that those locks are related, so if another piece of code takes locks in a different order, we could get a classic deadlock.
What if mono_alc_foreach
made a copy of the alcs
list while holding the lock, and then called g_slist_foreach
on the copy?
(And also we would need to protect each ALC, if it is collectible, from being collected while we're iterating)
@lambdageek hi, I have adjusted according to your comments, the only thing not did
I found the alc is not cleanup now and other function like |
hi, can you review it again? @lambdageek |
comment so you don't forget |
hi, can this got merged or anything to adjust? |
for (guint i = 0; i < alcs->len; ++i) { | ||
alc = (MonoAssemblyLoadContext*)g_ptr_array_index (alcs, i); | ||
MonoJitMemoryManager *jit_mm = (MonoJitMemoryManager*)(alc->memory_manager->runtime_info); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be:
MonoJitMemoryManager *jit_mm = jit_mm_for_mm (alc->memory_manager);
Why do we need to iterate over all ALCs ? |
because the |
hi, we found if the code is not in default alc, it's not
invalidate_transformed
when metadata updateclear two places
// FIXME: Enumerate all memory managers
@vargaz @lambdageek @lateralusX can you take time to reivew it?
the
interp_jit_info_foreach
will be called by ep-rt-mono.c