[mono] Fix interface call in case of reabstraction - #131219
Conversation
An interface is assigned an offset in the vtable of a class that implements it, so that a call through a method on that interface will do a call through the vtable slot. There are multiple places where this offset computation happens, for example `mono_class_setup_count_virtual_methods`. Method reabstraction doesn't create a new slot. Interface calls are dispatched through imt slots that are placed before the vtable. A slot is initialized in `build_imt_slots` so that it calls through the corresponding vtable slot. For slots where we have collision of multiple interface methods, we emit some thunk that does repeated checks to dispatch to the right method. The `build_imt_slots` method didn't handle reabstraction so the vtable slot to be called for an interface method was incorrectly computed. This would appear to suggest that all cases of interface method reabstraction are broken. However, it wasn't the case because even though we incorrectly initialize the imt_slot with the wrong implementing method, `mini_resolve_imt_method` will end up patching the imt_slot if we don't have collisions, over-writting with the correct target. Added a testcase with multiple reabstracted methods on a type.
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
|
Tagging subscribers to this area: @steveisok, @vitek-karas |
There was a problem hiding this comment.
Pull request overview
This PR updates Mono’s IMT slot construction to ignore reabstracted interface methods when computing the vtable slot to call, preventing incorrect interface dispatch for IMT slots that require collision trampolines. It also adds a regression test that defines an interface with many reabstracted members to validate dispatch stability.
Changes:
- Skip reabstracted interface methods in
build_imt_slots(both the generic-interface fast path and the normal path) so they don’t affectvt_slotaccounting or IMT entry construction. - Add a new regression test project and test case exercising interface dispatch in the presence of many reabstracted members.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/mono/mono/metadata/object.c | Skips reabstracted methods while building IMT entries so vtable slot selection remains correct, especially for collision trampolines. |
| src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/ReabstractedInterfaceMethodIMT.cs | Adds a regression test that invokes many interface methods on a type whose interface includes many reabstracted members. |
| src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/ReabstractedInterfaceMethodIMT.csproj | Adds the test project file for building/running the new regression test. |
lateralusX
left a comment
There was a problem hiding this comment.
LGTM! nit: maybe add a generic version of the test to hit the generic path as well?
1c2977a to
8e751a7
Compare
|
/ba-g unrelated wasm |
|
/backport to release/10.0 |
|
Started backporting to |
An interface is assigned an offset in the vtable of a class that implements it, so that a call through a method on that interface will do a call through the vtable slot. There are multiple places where this offset computation happens, for example
mono_class_setup_count_virtual_methods. Method reabstraction doesn't create a new slot.Interface calls are dispatched through imt slots that are placed before the vtable. A slot is initialized in
build_imt_slotsso that it calls through the corresponding vtable slot. For slots where we have collision of multiple interface methods, we emit some thunk that does repeated checks to dispatch to the right method. Thebuild_imt_slotsmethod didn't handle reabstraction so the vtable slot to be called for an interface method was incorrectly computed. This would appear to suggest that all cases of interface method reabstraction are broken. However, it wasn't the case because even though we incorrectly initialize the imt_slot with the wrong implementing method,mini_resolve_imt_methodwill end up patching the imt_slot if we don't have collisions, over-writting with the correct target.Added a testcase with multiple reabstracted methods on a type.
Fixes #129496