Skip to content

[mono] Fix jit_mm mismatch in delegate trampoline creation for dynamic methods#125583

Merged
lewing merged 2 commits intomainfrom
fix/mono-delegate-jit-mm-mismatch
Mar 16, 2026
Merged

[mono] Fix jit_mm mismatch in delegate trampoline creation for dynamic methods#125583
lewing merged 2 commits intomainfrom
fix/mono-delegate-jit-mm-mismatch

Conversation

@lewing
Copy link
Member

@lewing lewing commented Mar 15, 2026

Problem

mono_create_delegate_trampoline_info used a merged memory manager (class + method) to select which jit_mm->delegate_info_hash to insert into, but mono_jit_free_method used jit_mm_for_method (method-only) to look up and remove entries. When the merged mm differed from the method mm, cleanup would silently fail to remove the delegate_info_hash entry and could trigger the assertion at mini-runtime.c:3006:

g_assert (dpair->method == method);

Additionally, the two hash table insertions (delegate_info_hash and dyn_delegate_info_hash) used separate lock/unlock regions, creating a window where a concurrent mono_jit_free_method could see an inconsistent state — finding a dpair in dyn_delegate_info_hash that hadn't been fully set up yet, or missing one that was already in delegate_info_hash.

This manifests as a random assertion failure on WASM with AOT and threads enabled:

[MONO] * Assertion at mini-runtime.c:3007, condition '' not met

Fix

  1. For dynamic methods, use jit_mm_for_method consistently (matching the cleanup path in mono_jit_free_method) instead of the merged memory manager.
  2. Perform both hash table insertions (delegate_info_hash and dyn_delegate_info_hash) under a single lock to eliminate the partial-state window.

Fixes #120059

…c methods

mono_create_delegate_trampoline_info used a merged memory manager
(class + method) to insert into delegate_info_hash, but
mono_jit_free_method used jit_mm_for_method (method-only) to look up
and remove entries. When the merged mm differed from the method mm,
cleanup would silently fail to remove the delegate_info_hash entry,
and could also fail to find dpairs tracked in dyn_delegate_info_hash
since they were stored in a different jit_mm.

Additionally, the two hash table insertions (delegate_info_hash and
dyn_delegate_info_hash) used separate lock/unlock regions, creating a
window where a concurrent mono_jit_free_method could see an
inconsistent state.

Fix both issues:
1. For dynamic methods, use jit_mm_for_method consistently (matching
   the cleanup path in mono_jit_free_method).
2. Perform both hash table insertions under a single lock to eliminate
   the partial-state window.

Fixes #120059

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 15, 2026 15:39
@lewing lewing marked this pull request as draft March 15, 2026 15:43
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a Mono JIT runtime bookkeeping mismatch for delegate trampoline info associated with dynamic methods, ensuring the same MonoJitMemoryManager is used for both insertion and cleanup, and making the insertion atomic with respect to concurrent cleanup.

Changes:

  • For dynamic methods, use jit_mm_for_method(method) (instead of a merged class+method memory manager) when selecting the delegate_info_hash owner.
  • Insert into delegate_info_hash and dyn_delegate_info_hash under a single jit_mm lock to avoid transient partial state during concurrent mono_jit_free_method.

You can also share your feedback on Copilot code review. Take the survey.

@lewing
Copy link
Member Author

lewing commented Mar 16, 2026

/ba-g ios failures are infra

@lewing lewing merged commit 7a7c166 into main Mar 16, 2026
73 of 76 checks passed
@lewing lewing deleted the fix/mono-delegate-jit-mm-mismatch branch March 16, 2026 15:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

C# WebAssembly with AOT - Assertion at /__w/1/s/src/mono/mono/mini/mini-runtime.c:3007, condition '<disabled>' not met

3 participants