Skip to content

Conversation

@vargaz
Copy link
Contributor

@vargaz vargaz commented Sep 19, 2022

Mostly fixes #75801.

Some restrictions still remain, mostly methods with generic arguments like INegator`1<T>:NegateIfNeeded<Vector128<T>>.

@vargaz vargaz removed the request for review from SamMonoRT September 19, 2022 14:56
@ghost ghost assigned vargaz Sep 19, 2022
@vargaz vargaz force-pushed the gshared-static-virtual branch from 2862420 to 757df67 Compare September 19, 2022 18:18
@vargaz
Copy link
Contributor Author

vargaz commented Sep 19, 2022

/azp run runtime-wasm

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@vargaz vargaz force-pushed the gshared-static-virtual branch from 757df67 to 3d2a7f6 Compare September 20, 2022 03:50
@vargaz
Copy link
Contributor Author

vargaz commented Sep 20, 2022

/azp run runtime-wasm

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@vargaz vargaz marked this pull request as draft September 20, 2022 16:05
@vargaz vargaz removed the request for review from lambdageek September 20, 2022 16:05
Mostly fixes dotnet#75801.

Some restrictions still remain, mostly methods with generic arguments like
INegator`1<T>:NegateIfNeeded<Vector128<T>>.
@vargaz vargaz force-pushed the gshared-static-virtual branch from 3d2a7f6 to 2db82b2 Compare September 21, 2022 19:02
@vargaz
Copy link
Contributor Author

vargaz commented Sep 22, 2022

This approach is not going to work, for example:

public class Tests
{
        private interface INegator<T> where T : struct
        {
            static abstract bool NegateIfNeeded(bool equals);
        }

        private readonly struct DontNegate<T> : INegator<T> where T : struct
        {
            public static bool NegateIfNeeded(bool equals) {
                Console.WriteLine (typeof (T));
                Console.WriteLine (typeof (T));
                Console.WriteLine (typeof (T));
                Console.WriteLine (typeof (T));
                return equals;
            }
        }

        private readonly struct Negate<T> : INegator<T> where T : struct
        {
            public static bool NegateIfNeeded(bool equals) => !equals;
        }

    private static int IndexOfValueType<TValue, TNegator>()
            where TValue : struct, INumber<TValue>
            where TNegator : struct, INegator<TValue>
    {
        for (int j = 0; j < 1000; ++j) {
            for (int i = 0; i < 100000; ++i)
                TNegator.NegateIfNeeded (true);
        }
        return 0;
    }

The AOT compiler will compile IndexOfValueType(TValue_BYTE, TNegator_INST).
The IL sequence for the call is:

constrained. !!TNegator
call       bool class Tests/INegator`1<!!TValue>::NegateIfNeeded(bool)

This PR will resolve the called method to:
Tests/DontNegate`1<T_BYTE>:NegateIfNeeded (bool)
where T_BYTE is the inner type variable of TNegator_INST.
The problem is that this type variable is not part of the calling method so at runtime, when we try to inflate Tests/DontNegate`1<T_BYTE>:NegateIfNeeded (bool) with the real type arguments (byte, Negate<byte>), it won't be inflated so we end up calling an open method.

@vargaz
Copy link
Contributor Author

vargaz commented Sep 22, 2022

Closing in favor of:
#76033

@vargaz vargaz closed this Sep 22, 2022
@vargaz vargaz deleted the gshared-static-virtual branch September 22, 2022 19:26
@ghost ghost locked as resolved and limited conversation to collaborators Oct 23, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

mono AOT compiler cannot resolve and inline static virtual calls in gshared methods

1 participant